5

I'm using swagger to prototype a RESTful API and I got to a situation where one property is part of a resource but not always should be filled.

Let's say my resource is stores.

Basic endpoints would be:

GET: /stores - returns a list of store

GET: /stores/{storeId} - returns a single store

Say store is defined along the lines of:

Store {
  id: integer,
  name: string,
  pictures: array[]
}

But when returning the list of stores, also returning every store's list of pictures is overkill. Pictures should be only returned for a single store request.

I'm confused on how to model that situation. On swagger, both methods responses are associated with a store object.

Should I split store into two objects and definitions so that each method return a different type even though only one property is different?

Should I use a query string parameter so that the consumer can choose whether or not pictures should be filled? Something along the lines of:

GET: /stores?fillPictures=false or maybe

GET: /stores?detailed=false

When choosing the second option, the definition of a single store would be the same no matter which endpoint is being accessed. That would mean an empty property would be transmitted to the consumer for every non detailed (with pictures) request. Should that be a concern?

Can someone shed some light on how to handle this scenario in a RESTful way? Maybe you know some API with a similar operation?

Thanks in advance.

1
  • Would the pictures array contain actual picture data or links where the pictures can be obtained when needed? Commented Jan 11, 2017 at 17:43

2 Answers 2

10

GET: /stores - returns a list of store

GET: /stores/{storeId} - returns a single store

These are two different resources (a store, and a list of stores), so it is fine that they have different data.

The resource representing a list of stores can contain just enough information for the client to navigate to the store it might want. So it might be something like

Request
    GET /stores

Response
  200 - OK

  {
    stores: [
      {id: 34, name: "Walmart", url: "/stores/34"},
      {id: 35, name: "Best Buy", url: "/stores/35"}
    ]
  }

The client can then navigate to the individual store to get any further information it needs about a particular store.

3
  • 2
    You can calibrate this to precisely meet your needs: /stores could include one thumbnail picture, and then /stores/{storesId} or /stores/{storeId}/pictures could provide every available picture, with that link included in your first response.
    – Gaurav
    Commented Jan 11, 2017 at 18:40
  • You're right. Different resources. @Gaurav what you wrote is exactly how i'm going. I was hanging too much on the fact that my swagger specification would have two very close definitions but I guess that's ok. Commented Jan 12, 2017 at 14:11
  • 1
    @RodrigoLira - I think that you've identified a key point in your comment. Do not conflate a clean swagger spec with a well designed API.
    – D.Shawley
    Commented Jan 13, 2017 at 13:03
0

If you have a many/many relationship (ie. a picture can go with mutiple stores) I would go with

Store {
  id: integer,
  name: string,
  pictureIds: array[]
}

and a separate endpoint

POST: /getPictures pictureIds: array[]

If its a one store per picture relationship :

Store {
  id: integer,
  name: string
}

POST : /getPicturesForStores  storeIds : array[]

Both these methods allow you to get a list of stores, and display all the pictures related to that list in two requests without duplicating data.

POST is required for 'get many' style requests as there is prohibitively small limit on the number of characters allowed in a url query string

Not the answer you're looking for? Browse other questions tagged or ask your own question.