RESTful related resource using JSONAPI schema - rest

I am following the jsonapi schema to return a standardised response from a web API. I want to reduce the number of HTTP requests to get related information so it looks like I want to use compound documents to return (for example) an article and two related comments.
I somewhat understand this but I am wondering what the RESTful GET request would be? I am thinking something like
http://api.mysite.com/v1/articles/1?comments=2
I like to be explicit but are the request parameters necessary in order to return related information from a resource?

Sound like you want /v1/articles/1?include=comments&limitComments=2
Where limitComments is an API-specific param (note member name requirements)
http://jsonapi.org/format/#query-parameters
http://jsonapi.org/format/#fetching-includes
Alternatively, you could /v1/comments?include=articles&filter[articles]=1&page[size]=2
See http://jsonapi.org/recommendations/#filtering
and http://jsonapi.org/format/#fetching-pagination

Related

Is it a good practice to use 'createModel' in REST?

I'm looking for a best way for implementing an endpoint of REST-full application that will be responsible for creating a new library orders. Let's assume that I have the following resources.
If I want to get all books of a particular author I can use the next endpoint:
HTTP GET
api/books/author/123
If I want to fetch all orders of a particular book I can use the endpoint provided below:
HTTP GET
api/books/456/orders
My question is what will be the most suitable URL and a request model for an endpoint that will create orders?
From my perspective it can be
HTTP POST
api/books/456/orders
And one more question. Is it a good practice in REST to use request models like CreateOrder? If I want to create a REST-full web application can I use the following request model:
class CreateOrder
{
AuthorId: number;
BookId: number;
ClientId: number;
}
Sometimes it makes me confused. Should request models look like our resources or not?
Let's assume that I have the following resources.
Your "resources" look suspiciously like "tables". Resources are closer to (logical) documents about information.
what will be the most suitable URL and a request model for an endpoint that will create orders
For the most part, it doesn't matter what URL you use to create orders. In a hypermedia application (think HTML), I'm going to submit a "form", and the meta data associated with that form are going to describe for the client how to compose a request from the form data.
So the human, or the code, that is manipulating the form doesn't need to know anything about the URL (when is the last time that you looked to see where Google was actually sending your search?)
As far as general purpose web components are concerned, the URL/URI is just an opaque identifier - they don't care what the spelling means.
A thing they do care about is whether the spelling is the same as something that they have cached. One of the consequences of a successful POST /x message is that the cached representation(s) of /x are invalidated.
So if you like, you can think about which cached document should be refreshed when an order is created, and send the request to the identifier for that document.
Should request models look like our resources or not?
It's not necessary. Again, think about the web -- what would the representation of create order look like if you were POSTing form data?
clientId=1&bookId=2
or maybe
bookId=2&copies=3
If the "who is creating an order" is answered using the authorization headers.
In our HTTP requests and responses, we are fundamentally sending message representations - sequences of bytes that conform to some schema. There's no particular reason that those sequences of bytes must, or must not, be the same as those we use elsewhere in the implementation.
Your end-point does not need to always start with /books. You can introduce another end-point /orders for creating or getting orders. So , to create an order , you can :
HTTP POST
api/orders
And does the 'request model' that you mean is the HTTP request body structure ? If yes, it does not need to be 100% match with your back-end persisted/domain model. Just include enough parameters that the server needs to know in order to create an order. (e.g. Include bookId rather than the whole book object etc.)
BTW , to get all books for a particular author , it is more common to use query parameter such as :
HTTP GET
api/books?authorId=123
What you are doing is not REST, it is CRUD over HTTP. REST does not care about your URI structures and resources are very far from database tables. If CRUD is all you need, then download a CRUD generator library https://github.com/search?q=crud+generator&type=Repositories, which will generate all the upper and you won't need to write it manually.

What could be a valid URI template for REST API handling a GET HTTP request with multiple parameters?

I am developing a RESTful API that handle a GET request needing 2 parameters.
I try to explain better the use case: This API will return the latest price of a specific commodity (the commodity_id is one parameter) in a specific market (the market_id is the second parameter).
So what can be a valid URI template for this pourpose?
Something like this:
/latest_commodity_price/{commodity_id}/{market_id}
or something like this:
/latest_commodity_price/{commodity_id}?market_id={market_id}
or something like:
/latest_commodity_price?commodity_id={commodity_id}&market_id={market_id}
Or what else?
In RESTful ways your approach starts at the wrong position. REST means you are querying resources. So the URI should start with the resource you are querying your API for.
/commodity/{commondity_id}
Then you want to have a list of prices for a market. This sound like you query your API to retrieve a list of prices for the commodity:
/commodity/{commondity_id}/prices
Finally you are filtering the list of prices. I recommend doing filtering with the query parameters:
/commodity/{commondity_id}/prices?market_id={market_id}&latestPrice=1

Design a REST API in which a search request can take parameters for multiple Queries

I have to design a REST API in which a search request can take parameters for multiple Queries ( i.e. when the client make a call using this API, he should be able to send parameters to form multiple queries).
We have an existing API where we are using GET and it takes multiple parameters which together forms a single Query and then this API call returns the response for this query.
e.g. currently I can pass firstName, lastName, age etc in the request and then get back the person.
But now I have to enhance this service(or have a separate service) where I should be able to send parameters like firstName1, lastName1, age1 to search person1 ; firstName2, lastName2, age2 to search person2 and so on.
Should I use POST for the new API and then send list of parameters(params for query1, params for query2 and so on)?
Or is there a better approach.
We are using Spring Boot for REST implementation.
Its better to use POST because GET is good for 2,3 parameter but when you have a set of parameter or object then POST is Good.
The best thing to do here will be do POST and then return a JSON object with all the details of the Person in an array.
That way it will be faster and you would not have to deal with long urls for GET.
Also GET has limitations regarding the length of the request whereas there is no such limitation in case of POST.
It is really hard to give a right answer here. In general sending a GET request does have the advantage that you can leverage caching easily on a HTTP level, e.g. by using products like varnish, nginx, etc. But if you already can forsee that your URL including all params you'll have to send a POST request to make it work in all Browsers.
RESTfull architecture should respect the principle of addressability.
Since multiple users can be accessed through a unique request, then ideally this group of user should get an address, which would identify it as a resource.
However I understand that in the real world, URIs have a limited length (maximum length of HTTP GET request?). A POST request would indeed work well, but we lose the benefit of addressability.
Another way would be to expose a new resource : group,.
Lets suppose that your current model is something like this :
.../users/{id}
.../users/search?{arg1}={val1};{arg2}={val2}
You could eventually do something like :
.../users/groups/
.../users/groups/{id}
.../users/search?group={id}
(explanation below)
then you could split your research in two :
first a POST on .../users/groups/ with, as proposed by other response, a JSON description of the search parameters. This request could scan the .../users/groups/ directory, and if this set of parameters exists, return the corresponding address .../users/groups/{id}. (for performance issues you could for instance define {id} with a first part which would give the number of users requested).
Then you could make a request for this group with a GET with something like this : .../users/search?group={id}.
This approach would be a bit more complex to implement, but is more consistent with the resource oriented paradigm.

RESTfully Fetching by Attribute

Which of the following URLs is more RESTful compliant when it comes to fetch only items that have a certain value for attribute?
GET: /items/attribute/{value}
GET: /items/findByAttribute?attribute={value}
GET: /items?attribute={value}
Having in mind that GET: /items returns all items.
Example
GET: /shirts/color/FF9900
GET: /shirts/findByColor?color=FF9900
GET: /shirts?color=FF9900
I think that the last option is the correct one ;-)
Here are some comments for the others:
Generally the path element right after the one that corresponds to the list resource is the identifier of the element. So if you use something at this level, it could be considered as an identifier...
You can have resource to manage a particular field but the URL would be something like /items/{itemid}/fieldname.
You shouldn't use "action names" within the URL (in your example findByAttribute). The HTTP method should correspond to the "action" itself. See this answer if you want to support several actions for an HTTP method: How to Update a REST Resource Collection.
There is a question about how to design search filter: How to desing RESTful advanced search/filter. I think that your use case if a bit simple and using query parameters matches for you.
Otherwise I wrote a post about the way to design a Web API. This could be useful for you. See this link: https://templth.wordpress.com/2014/12/15/designing-a-web-api/.
Hope it helps you,
Thierry
Most certainly this one
GET: /items?attribute={value}
Why?
GET: /items/attribute/{value} is wrong because with REST, url segments represent resources, attribute is not a resource
GET: /items/findByAttribute?attribute={value} is wrong for the same reason really. findByAttribute is not a resource
Using url queries to filter by attributes is perfectly fine, so go with that.
URI semantics are irrelevant to REST. It doesn't make sense to ask which URI is more RESTful. What makes an URI RESTful or not is how the client obtains it. If he's reading URI patterns in documentation and filling placeholders with values, it's not RESTful. If this is news for you, I recommend reading this.
With that in mind, all three examples can be RESTful if the server provided that URI template to the client as a link to query the collection resource filtering by that value, but 3 is definitely the best option since it follows a more conventional query syntax. I wouldn't use 2 since it implies a method call and it looks too RPC for my taste, and I wouldn't use 1 since it implies for a human that it will return only the attribute as a resource.

How to define transforms on a resource in a REST way?

I'm designing a REST api, following best practices, including a form of hypermedia/hateoas. I'm using jsonapi for the design guidelines, which seems to be pretty complete.
Currently, I have a need for:
combining 2 resources in a response (a Resource A and a related Resource B). I do this using the Compound Documents - structure as specified in jsonapi. Or also commonly known as resource expansion
formatting the result of 1. in a specialized way so it can be readily consumed by a specialized client that expects said formatting.
My problem is with 2. How do I correctly represent this in a REST-way? It seems I may need a separate endpoint, but that wouldn't be 'RESTy', since that implies a separate resource, while it's just a transformation of the output of the same resource.
Any references on how to do this?
You could use a header or a query param to handle this.
When the client needs specific formatting, they could add an additional header to the request something like Format:Indented or something like http:\\myapp.com\resouces\myresource?format=indented
Or if the server is formatting and wants the client to know that the response is pre-formatted, the server could add a Format response header to notify the client that response is formatted.