3

Suppose we are building one-page app with two views: list view and detail view.

In list view, we present a list of objects with just their names and maybe some more minimal data.

In detail view, we present all possible fields of particular object.

Hence the question: when we GET /api/items/, should we or should not to JSON-encode all fields of the objects listed, or just those presented in list view?

In other words, if we show list of food like

Name     Price
Potato   1
Milk     2

does our API need to respond with JSON like this:

{ 
    [
         {
             "name": "Potato",
             "quantity": "1 kg",
             "origin": "Egypt", 
             "manufacturer": "Egypt Farmers",
             "price": 1,
             "packaging": "String bag",
             "_type": "Food"
         },
         {
             "name": "Milk",
             "quantity": "1 litre",
             "origin": "Finland", 
             "manufacturer": "Valio",
             "price": 2,
             "packaging": "Tetra Pak",
             "_type": "Food"
         },
    ]
}

or like this:

{ 
    [
         {
             "name": "Potato",
             "price": 1,
             "_type": "Food"
         },
         {
             "name": "Milk",
             "price": 2,
             "_type": "Food"
         },
    ]
}
Opal
  • 81,889
  • 28
  • 189
  • 210
Mikhail Batcer
  • 1,938
  • 7
  • 37
  • 57
  • @Opal It is not exactly a problem. I'm seeking ways to make improvements in our system, and for that I try to figure out best practices. I prefer your answer over jeffm13's, because I liked the idea to include in request fields of resources to be returned. – Mikhail Batcer Oct 03 '15 at 15:49

2 Answers2

3

The RESTful API should concentrate on the resources that are represented, not necessarily how those resources are used.

In a master/detail scenario, typically the master will contain details of the master object, and include a list of its details (including a link to the API for each detail resource. So /api/items/ might look like this:

{
    items: [
       { name: 'item 1', href: '/api/items/1' },
       { name: 'item 2', href: '/api/items/2' }
    ]
}

The detail resource would contain properties of an individual item in the items list. So the /api/items/{itemName} api might look like this:

{
    name: 'item 1', 
    color: 'blue', 
    weight: 100,
    id: '/api/items/1'
}

So this would probably be closest to your second scenario. There are a number of advantages to this model: it probably matches the domain model that your api is accessing, it makes each api very simple and single-purpose, it's easy to scale, even to very large lists. The disadvantage is that it may lead to more complexity on the client.

jeffm13
  • 41
  • 5
2

The answer as usual may be: it all depends ;)

  1. In case of the connection is limited or unstable (e.g. mobile connection like LTE or even wifi) the best idea is to return the whole list of resources with all fields filled and use the same data on both views. In the company I work for we often take this approach since our backend almost always provide data for mobile applications.

  2. The second idea is to use a mechanism called field or resource expansion. In general a request is made to the endpoint and fields of resources to be returned are included in this request:

    /api/items?fields=(name, quantity, origin, whatever)
    

    This mechanism is very convenient since you can use this endpoint to server multiple views without any performance loss.

  3. Personally I'd use two endpoints. An /api/items/ endpoint with field/resource expansion mechanism built-in (with a limited list of fields that can be expanded) and the second one /api/items/{itemID}/ to return a particular item with all the data. This is also the most RESTful approach.

Opal
  • 81,889
  • 28
  • 189
  • 210