Some general restful api design questions - api

A few general design questions:
Give the example here:
https://developers.google.com/+/api/latest/activities/list#nextPageToken
Why would the server return a token to retreive the next paginated result? Doesn't this break the idea of being stateless?
Why not just pass a MySQL like LIMIT name=value as the parameters? The server now has to return the number of pages I suppose...what am I missing?
I read many but this one was of interest:
REST Web Services API Design
The second reply, offers the following examples.
GET http://api.domain.com/user/<id>
GET http://api.domain.com/users
PUT http://api.domain.com/user/<id>
POST http://api.domain.com/users
DELETE http://api.domain.com/user/<id>
Makes sense but why are there two plural resources? Could one not assume that if "user" is queried and was NULL or not provided that "all" was intended? Likewise for POST? If plural is for improved readability - why is there not a "users" resource for DELETE?
Ultimately, I understand REST to mean...representation of a single resource - using HTTP verbs (GET, PUT, POST, DELETE) to essentially manage that resource - similar to CRUD.
EDIT | Lastly I also wanted to ask why Google API sends the API version in the URI instead of using HTTP headers? Is there a reason? For backwards compat with older clients?
Comments?

Why would the server return a token to retrieve the next paginated result? Doesn't this break the idea of being stateless?
Using this kind of mechanism for paginated result sets is completely standard and does not break the idea of being stateless. Consider the following example.
Suppose GET /users?after=<after> (where after is optional) is supposed to return the list of all users in a paginated fashion, say <= 4 per page.
The first request a client makes is GET /users with a response that might look like the following (formatted as JSON).
{
"users": [ "alex", "bob", "carter", "dan" ]
"more_after": "dan"
}
In this example, the more_after property designates there may be more users left in the user list. So the client then requests GET /users?after=dan and gets a second response that looks like the following.
{
"users": [ "edward", "frank" ]
}
The absence of the more_after property designates that this is the last page of users.
Now the question is: was the "dan" token used as the page separator something that breaks the "statelessness" property we want? Clearly the answer is no. The server doesn't have to remember anything between the two GET requests. There's no concept of a session. Any state that needs to persist between the two GET requests exists only client-side - that's the important distinction. It's completely acceptable - and often required - to have the client persist state between calls to the service.

Related

Multiple endpoints to expose different views of the same resource

I'm struggling to find an answer to this (perhaps because I'm not asking the question properly) ...
I'm building API to expose resources for a basic social networking service I'm creating.
My understanding is that the structure of URLs in an API is essentially a hierarchy, directory like structure. I think that means I can have multiple endpoints to reach the same resources or collections of resource links.
For example:
I have an endpoint
www.domain.api.org/users/{:uid}/posts
Which will return all posts sent by the user or that the user is tagged in. Seems ok, but what if I have an endpoint such as:
www.domain.api.org/posts
Which when hit with a http GET will return all public posts (i.e. all users' posts plus his friends' and public posts).
The difference is that the first URL points to user owned resources whereas the second to public ones (of which the users posts are included of course)
Are these okay or am I doing it the wrong / less sensible way?
To reiterate, can I have multiple endpoints which point to different contexts/views of the same resource?
Basically multiple endpoints for the same resources should be avoided. However in this particular case it does make sense.
What you can do is to introduce optional query param userId to the following endpoint:
www.domain.api.org/posts/?userId=<userId>
If this substitutes the first endpoint you mentioned that's the way to go.
I would like to add ontop of #Opal's answer.
Are these okay or am I doing it the wrong / less sensible way?
Ideally, like Opal mentioned, you would use queryParams in your url. For many applications I have build, I don't know the uids returned from the api beforehand, so selecting an item and passing it inside my url as a query parameter makes sense. But it also has the added benefit of having your key inside your url, allowing you to bookmark it, pass the url to another user and they will automatically see the same data you want them to see.
To iterate: Is your current implementation wrong? No, but ideally you would use a combination of both route parameters are query parameters to achieve this
To create an endpoints, you have to be sure that you have these information at once:
Name of the endpoint
Status: activate or not (required) - is the endpoint activated or disable
Service profile (required) - ID of the Service Profile assigned to the endpoint.
Tariff profile (required) - ID of the tariff Profile assigned to the endpoint.
You can add another optional informations, and be sure of the structure of your endpoint.
Hope this helps you.

RESTful way of referencing other resources in the request body

Let's assume that I have a resource called group with the following representation:
{
"id": 1,
"name": "Superheroes"
"_links": {
"self": {
"href": "http://my.api.com/groups/1"
}
}
}
Now let's say I want to create a new person instance by POSTing to /persons/1. Which of the following should I use for the request body:
Using ID
{
"name": "Batman",
"groupId": 1
}
Using link
{
"name": "Batman",
"group": "http://my.api.com/groups/1"
}
With the first method I access the id directly either to look up the related resource or eventually store the id in the database, when I persist the person instance. But with the other method, I either have to extract the id from the URI or, follow the link to load the related resource, and then find out its id. I really don't want to store the URI in the database.
With the latter option, seeing that the server controls the structure of the URI, is it fine for me to parse the id out of the link? Following the link back to the server itself seems odd, seeing that at this point we already have access to the information directly (we just need the id).
So to sum up, which of these options is best?
Use the id directly.
Use the link, but parse out the id.
Use the link, but access the link to get the resource instance, and then get the id.
TL;DR: Use simple ids.
More detailed explanation:
A straightforward approach is to create a person by POSTing to /groups/1/persons with a payload {"name": "Batman"}.
However, while such approach works for simple cases, the situation gets complicated if there are 2 resources that need to be referenced. Let's assume that a person also needs to belong to exactly one company:
GET /persons/1
{
"name": "Batman",
"group": 1, // Superheros, available at /groups/1
"company": 5 // Wayne Enterprises, available at /companies/5
}
Since there is no relationship between companies and groups, it is not semantically correct to create a person via POSTing to /groups/1/companies/5/persons or to /companies/5/groups/1/persons.
So let's assume you want to create a person with a request looking like this:
POST /persons
{
"name": "Batman"
"group": ???, // <--- What to put here?
"company": ??? // <--- What to put here?
}
Which brings us to the answer to your question:
Ease of use. Your API should be primarily designed for the ease of use. This is especially true, if you design a public API. Therefore, Option 2 (Use the link, but parse out the id) is out, since it imposes additional work for clients of your API.
Constructing search queries. If you want to be able to query persons which belong to the company 10 and the group 42, simple ids lead to more readable and less error-prone urls. Which of the following do you consider more readable?
URL with a simple id:
GET /groups/42?company=10
or URL with a url-encoded link:
GET /groups/42?company=http%3A%2F%2Fmy.api.com%2Fcompanies%2F10
I wouldn't underestimate the point of readability. How many times do you need to debug your API in various curls, logs, postmans, etc.
Development Links need to be parsed in the backend, while simple ids can be used directly. It's not about performance, but rather about additional work/tests you have to put in.
Endpoint maintenance. Imagine that your API endpoint evolves. You decide one day to switch to https or to include versioning in the url. This might break API clients, if they for some reason rely on structure of the links. Also, you might want to checkout if link parsing on your backend is done properly.
Argumentum ab auctoritate I know this is not a proper argument, but if you checkout APIs of large players, e.g. Twitter, Github or Stripe, they all use simple ids.
HATEOAS. One common argument in favour of links is that it is aligned with HATEOAS. However, as far as I know, this relates to additional links in API responses rather than using links in payloads of POST requests.
All in all, I would go for simple ids, since I haven't yet heard a compelling argument favouring links, which would beat the aforementioned.
You are missing two important things here.
You need a standard way to describe forms in the response, in this case your POST form.
The information about the group ids / uris, or how to get them has to be described in the form in a standard way.
For example a HTML FORM with a SELECT INPUT would be RESTful. The closest thing we got in json to do the same is json-ld and hydra. But if you are obsessed with hal, then use hyperagent forms or something like that. It will never be a standard, but if compatibility is not an issue, then it is good enough.
To answer your question, you should use the id, because the server knows how to interpret it. The client needs the resource identifiers, the server needs it only in the uri part of the request, not in the body.
From my experience, it is always best to go with the simplest solution for making requests.
The process of generating a new url and parsing it seems excessive to get a resource, whereas sending the id of the item you want seems much simpler.
Thus, I would send a request in the form:
{
"name": "Batman",
"group": 1
}

Is it ok for a REST api to be exposed via two HTTP methods?

The problem is that we have a complex query string for a search api and want to let the users have convenience of using body instead. So we want to allow both GET and POST(or PUT).
I understand that there will be a debate of search being a read only operation and it should be GET only as per REST standards. Also PUT is not cache friendly as i understand.
But i also know that its ok to deviate at times from the REST standards. But does it make sense to have two methods for client's convenience?
Using POST directly to query data is not a good thing, precisely for the reasons that you mentioned. If your search string is complex, perhaps you could simplify things by splitting the querying process in two steps - one involving a POST, and another one involving straight GETs.
The first step creates a query template using the POST. The query string is sent via message body, and becomes a new resource that users can query through GET. Query string allows for parameters, in a way similar to SQL queries. Taking a wild guess at how your query might look, here is an example:
(userName = $name) || (createdBefore > $asOf && deleted=false)
Your users would POST this in a message body, and get a new resource identifier back. This resource identifies a parameterized "view" into your data. Let's say the resource id for this view is aabb02kjh. Now your users can query it like this:
https://app.yourserver.net/aabb02kjh?name=airboss&asof=20140101
This adds some complexity to your API, but it lets users define and reuse query templates with very simple and standard query strings.
Interesting question. I mean by POST -> PUT,DELETE there are common workarounds for overriding HTTP methods:
sending a _method hidden input field with the post data
sending a _method query param in the URL
sending an X-HTTP-Method-Override header with the post
etc... So if they are valid (I am not sure about that), then you could use the same approach by GET as well.
According to REST constraints: cache and the uniform interface, and the HTTP method definitions, you have to use GET by retrieval requests. There are only a few URL query languages to make URLs readable, for example RQL, but you can always pick your favorite query language and serialize it for URL usage...
Another interesting approach to add link descriptions about the URL. (But that is very new for me either.)

RESTful API GET method parameters

We are creating a RESTful API (PHP on apache server) which will communicate with an Android application. Im new for this so excuse me if my question is dumb.
I want to ask for data from the api so I need to use GET method in the request taking into account the semantics. I have to send some additional data to specify what data am I requesting. In GET requests, I cannot send form data fields so how should I attach the data?
Using POST (but this is not semantic)
request header: POST http://example.com/api/v1/serials
request data: date_from=2013.01.01&date_to=2014.01.01&userid=112&is_in=0&starts_with=afx00
using GET and adding url params (I don't know if is this a good practice in a REST API)
request header: GET http://example.com/api/v1/serials?date_from=2013.01.01&date_to=2014.01.01&userid=112&is_in=0&starts_with=afx00
or making well formed URIs with no url params in GET (not sure about this as well.)
request header: GET http://example.com/api/v1/serials/date_from/2013.01.01/date_to/2014.01.01/userid/112/is_in/0/starts_with/afx00
Which one fits the best in the RESTful API architecture? Which should I use and why? Or maybe are there any other options for what I want?
Without question using URL parameters is best. It allows consumers to query for serials using their choice of filters. Your API should support returning results based on UserId alone, or a date range, or both. Or other combinations of inputs that make sense.
Embedding the key/value pairs of the filter in the resource path is an anti-pattern. It's difficult to understand what each path element means, and you would need to contort your routing engine to accommodate additional filter criteria. It also provides no flexibility in terms of choosing what filter criteria to use - you would in fact need to construct multiple resources paths for each combination of filters. And there is the management of ordering each pair (with URL params, ordering doesn't matter). Probably more reasons to avoid this, but those are the first that spring to mind.
Bot GET methods can be used. It is your choise. But I'll prefer using url params. It is easier.

Consuming a REST API endpoint from a resource ID

Lets consider the following flow to a RESTfull API:
API root
|
v
user list
|
v
user details
|
v
user messages
Suppose I have a client to consume the API, and I want to retrieve messages from a user with ID 42.
From what I've been studying, my client is not supposed to know how to "build" urls, and it should follow the links given by the API.
How should I do to retrieve messages for the user with ID 42?
The only way I can think is "walk" the whole API from it's root to user messages, which doesn't look very pretty or efficient to me.
Eg:
1 - GET / and get the link to the list of users
2 - GET /user/?id=42 and get the link to details of the user with the ID 42
3 - GET /user/42/ and get the link to user 42 list of messages
4 - GET /user/42/messages/ and finally get the user messages
Did I get something wrong? Is this the right way according to Roy's Fielding paper?
Or is it ok to just assume the messages url is "/user/{id}/messages/" and make the request directly?
Use URL templates in your API root. Let the client consume the API root at runtime. It should look for a URL template named something like "user-messages" with the value of "/user/{userid}/messages/". Then let the client substitute "42" for "{userid}" in the template and do a GET on the resulting URL. You can add as many of these URL templates you want for all of the required, often used, use cases.
The difference between this solution and a "classic" web API is the late binding of URLs: the client reads the API root with its templates at runtime - as opposed to compiling the client with the knowledge of the URL templates.
Take a look at the HAL media type for some information about URL templates: http://stateless.co/hal_specification.html
I wrote this piece here some time ago to explain the benefits of hypermedia: http://soabits.blogspot.dk/2013/12/selling-benefits-of-hypermedia.html
I believe what your real concern is should you go about implementing HATEOAS or not. Now as it's an integral part of REST specifications, it is recommended that each entity should have a link to it's child entity that it encompasses. In your case, API ROOT should show list of users with each "user" having a link (/root/users/{id}) to corresponding user's details. And each User details entity will contain a link to the list of "messages" (/root/users/{id}/messages) which, finally, inturn encompass the link to the actual message detail as well (/root/users/{id}/messages/{messageId}). This concept is extremely useful (and thus a part of the specifications) because the client doesn't need to know the url to where your entity is exposed. For example, if your users were on http://users.abc.com/rest/users/{id} but your messages were on http://messages.abc.com/rest/{userId}/messages/{messageId}, the user entity that encompasses the list of "messages" will already have link embedded to point to the right resource on a different server.
Now that being said, I haven't actually seen many REST implementations out there (I must admit I do not have TOO MUCH of an experience, but enough to give an opinion) where HATEOAS is being used widespread. In most cases the resources are almost always on the same server (environment) and the paths to resources are almost always relative to the root url.Thus, it doesn't make sense for the clients to parse out the embedded links from the object when they can generate one by themselves, especially when the client would like to provide access to a resource directly (View the message directly without getting the user entity provided you already know what the messageId is).
In the end, it all depends on how close do you want your REST implementations to that of specifications and what kind of clients are you going to have. My 2 cents would be: if you have time, implement REST with HATEOAS and feel proud about it :). There are libraries out there that will make this implementation (HATEOAS) somewhat transparent to you REST implementation (I believe spring has one, although not very mature. You can look at it here). If you are like me and don't have much time to go that route, I think you can continue with a normal REST implementation without HATEOAS and your clients will still be OK with it (or so I hope!)
Hope this helps!
I found this article about hacking urls: Avoid hackable URLs.
There is a very interesting discussion about the topic of this question in the comments section.