Way to specify resource's fields list in RESTf

2019-03-09 17:30发布

问题:

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

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

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

回答1:

I'd go for option 2 IMHO.

So 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

Edit: Looking back at this I’d change the request to be:

/posts/42?fields=subject,author_name

/post/42 is the resource, not fields.



回答2:

Have been doing research into this as well and was pointed towards Facebook's GraphQL as an alternative to requesting a restful api with the fields wanted. It is still in the very early stages but seems very promising.

https://facebook.github.io/react/blog/2015/05/01/graphql-introduction.html

EDIT: Reproduced from the URL:

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
    }
  }
}