43

I have a RESTful API within a web-service with resources such as users, posts and so on. When I make a request for a list of posts (GET /posts), I want to retrieve an array of posts only with limited data for each post (i.e. subject, author name). When I make a request for a concrete post (GET /posts/42) I want to retrieve the full list of post object fields, including big post body, additional info about likes count, comments count. I suppose there exist many ways to solve this problem.
In my mind, the three most obvious are:

  1. Explicitly specify a fields list on every request (/posts?fields=subject,author_name and /posts/42?fields=subject,body,createAt,author_name,comments_count,likes_count, etc...).
  2. Explicitly specify a fields list only if it differs from the default fields list.
  3. Specify a fields list that should be excluded (or included) from (to) the default fields set if the desired fields set differs from the default.

I want to build a clear and useful API for my customers. Which way should I choose?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Ivan Velichko
  • 6,348
  • 6
  • 44
  • 90

2 Answers2

52

I'd go for option 2.

If the consumer just requests the resource URL (/posts/42) they receive the default fields.

Then consumers can alter the default response by defining values in the query string like:

/posts/42/fields?subject,author_name

This has worked well for me in the past and is how some other well know APIs work, e.g. Facebook

Although I'd change the request to be:

/posts/42?fields=subject,author_name

/post/42 is the resource, not fields.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Dan Rowlands
  • 1,382
  • 12
  • 18
  • I'd agree. It provides a low barrier to entry, so developers can explore and can easily see the default fields, but still gives the flexibility to ask for exactly what you want if you need to. – theon Aug 14 '13 at 21:25
  • I do option (2) also, but I allow `fields=*` to get all fields so that querying the full set is easy to do (esp. for a developer wanting to know or double check what that set is). – Lawrence Dol May 06 '14 at 22:16
13

Facebook's GraphQL is an alternative to requesting a RESTful API with the fields wanted. It is still in the very early stages, but seems very promising.

From GraphQL Introduction, by Nick Schrock:

A GraphQL query is a string interpreted by a server that returns data in a specified format. Here is an example query:

{
  user(id: 3500401) {
    id,
    name,
    isViewerFriend,
    profilePicture(size: 50)  {
      uri,
      width,
      height
    }
  }
}

(Note: this syntax is slightly different from previous GraphQL examples. We've recently been making improvements to the language.)

And here is the response to that query.

{
  "user" : {
    "id": 3500401,
    "name": "Jing Chen",
    "isViewerFriend": true,
    "profilePicture": {
      "uri": "http://someurl.cdn/pic.jpg",
      "width": 50,
      "height": 50
    }
  }
}
TylerH
  • 20,799
  • 66
  • 75
  • 101
ascrookes
  • 433
  • 5
  • 12