What is the proper way to communicate data wtih units in a REST payload? - rest

I am working on a REST api that shows numbers of different items, each in a unit. For example, storage capacity. I have a media type which defines this payload, but I feel that the REST api should not be in the business of formatting the numbers, and they should all be in a baseUnit, say bits. It's up to the UI to format that as they wish.
My question is - should the data "hint" as to the units say:
{ name: "capacity", number: 33333, units: "bits" }
on every piece of data to make it explicit, or is that something that has to be inferred through documentation?

Related

bulk GET using HATEOAS

I've seen many examples of HATEOAS where every resource has links to related resources. An API that returns N items of a certain resource per page, the client would probably need N calls to fetch any nested resource by consuming HATEOAS. For example:
GET city/documents:
[{
id: 1,
city: {
self: 'http://service.com/cities?filter=id==1'
},
document: { ... }
...
}, {
id: 2,
city: {
self: 'http://service.com/cities?filter=id==2'
},
document: { ... }
...
}]
FYI, the query parameter uses the FIQL syntax to define the filters.
Now, if the client was to fetch the city details for each document (to show on UI), it will probably need N additional calls. However in my case, the /cities API can additionally take multiple city ids like this: /cities?filter=id=in=(1,2) that can reduce N calls to one. Is there a way to articulate something like this using HATEOAS? I've read about the templates but not sure how should the template look like and how would client consume it?
I've seen many examples of HATEOAS where every resource has links to related resources. An API that returns N items of a certain resource per page, the client would probably need N calls to fetch any nested resource by consuming HATEOAS.
Yes. Less true in a world with Server-Push, where the server can proactively provide multiple resources in response to a query. If you imagine asking for a web page, and getting the html, and then also the images and the java script resources too, then you've got the right sort of idea.
API can additionally take multiple city ids like this: /cities?filter=id=in=(1,2) that can reduce N calls to one. Is there a way to articulate something like this using HATEOAS?
Yes.
Let's walk through it carefully. What you've done here is introduced a new resource, with identifier /cities?filter=id=in=(1,2). You might have another resource /cities?filter=id=in=(1,20) and another resource /cities?filter=id=in=(1,2000). In your implementation, these might be a "single endpoint" that extracts parameters from the identifier and uses them to generate the correct representation.
So what you get is something like a data transfer object - a large grained resource fetched in a single go.
I've read about the templates but not sure how should the template look like and how would client consume it?
The simplest example, which you have likely seen already, is a web form. You allow the client to provide the start and end elements, and the form processing takes that information and creates the specified URI from it.
/filtered-cities?start=1&end=2000
So the client needs to understand what the form is for, and how to identify the semantics of the different elements in the form. The agent needs to understand the processing rules that transfer the form data into the URI.
URI Templates are the same basic idea; they give you a domain agnostic language with which to describe where the parameters go in a resource identifier. The basic pattern is the same - there needs to be agreement about the semantics of the parameters, the server provides a URI, the client provides a parameter map, and the generic code can take care of the merge
uri = template.apply(parameterMap)
URI Templates aren't quite as powerful as forms; with a form, you can introduce a default value for a parameter, but there is no analogous capability in URI templates.
HAL-Forms may give you a better sense of how a form based approach might work in JSON.

Should this GET call return 204 or 200 with a body?

Say we have a rest api which aggregates data about a Person from other services. One of the Aggregator service routes is GET /person/(person id)/driverinfo which tells us whether the person is a licensed driver or not, license id, expiry date of license and the number of traffic violations. These data can be picked up by the Aggregator from one or more other services. This api will be used by a web page to show the "driver info" about a person. It will also be tested with automation.
Currently, the api gives 204 no content response for persons who never had a driving license. This is because one of the underlying apis gives a 204 for that scenario. So, it was decided that the Aggregator should do the same.
But, I believe that this is not a good response. Instead, we should return 200 with appropriate values for the fields. For example, licensed=false, licenseId = N.A. etc. when the underlying api gives a 204. I.e. the Aggregator should generate these fields and their values.
Which approach do you think is better and why ?
204 means something specific in HTTP; it says that the server found a representation of the requested resource, and that representation is zero bytes long.
Therefore, the real question is more like "Should we use a zero byte long message to describe a situation?". Maybe? If all of the fields in your message schema are optional, and we are trying to describe a representation that means that all of the fields are taking on their default values, then a zero byte array might be the right way to communicate that.
Within the context of HTTP specifically, the headers themselves are already significant in length (compared to zero), so I wouldn't expect there to be particularly compelling performance reasons to squeeze a signal down to zero length. For instance, if we were normally passing around application/json, I would expect that sending an empty object or array to be much more cost effective than sending nothing at all.

Modify Rest POST request behavior with query String

I have a resource which basically represents a number. I have two possible updates for this number: Set the number to a specific value or add a value to it. Now I'm confused if I can use the query string part of the URL to specify the desired behavior.
Something like this:
/resource/{id}/?mode=add
/resource/{id}/?mode=set
Or is there an alternative way two represent to update strategies for a rest resource?
An Alternative would be to extend the request body with this information but this since strange, since the request data should contain the data and not "meta information" for the request itself - as far as I understand REST apis.
The project is an ordinary angularjs (client) and java (server) project.

Handling RESTful representation structure difference between POST and GET

I'm designing a REST API and despite trawling a number of best practice guides I can't find much relating to the best practice of handling the disparity between representation structure needed for a POST vs the same representation structure returned from a GET.
GET for a dummy user representation might look like this:
{
"id": 1234,
"created": "2012-04-23T18:25:43.511Z",
"username": "johndoe#example.com",
"name": "John Doe"
}
However, POST for the same dummy user representation cannot specify certain properties (namely the id and created):
{
"username": "johndoe#example.com",
"name": "John Doe"
}
Obviously this is an overly simplified example but given that the user cannot specify certain fields (and it might not always be obvious which ones are pertinent to the applied method) is it best practice to create separate representations for each or to expect the most complete version and handle the data disparity transparently on the server?
Despite the apparent ease of having a single representation and handling the disparity server side I am worried that this would be a bad experience for a user if it wasn't clear which values can be specified (or altered using PUT for example). If the tendency is to create separate representations is there a naming convention to apply to the representation definition?
e.g. i_user for incoming user and o_user for outgoing user. Or user_full and user_min or user and .user etc.
Update: My overly simplified example perhaps didn't properly illustrate the issue. Imagine a representation that has 50 properties (for example a server representation with all its monitoring attributes - cpu, ram, temp, storage_drive_a, storage_drive_b, file_permission etc.) Of these 50 properties, 30 are read only properties and 20 of these are values that can be set.
First of all, the final semantics of the POST method are determined by the targeted resource, not by the HTTP protocol, as with the other methods, so your POST method can do anything you want, as long as you document it properly, and you are not replicating functionality already standardized by other methods.
So, in short, there's nothing wrong with having a different representation for POST and GET method.
However, asking for a best-practice in this case is pointless, because what defines the representation format is the media-type being used, not the method, but most of the so-called REST APIs around the internet use generic media-types for everything and clients rely on URI semantics to know which resource they are dealing with, which is not RESTful at all. Basically, you are asking for the best-practice for a problem that doesn't really exist in REST when things are done properly.
So, to answer your question, you can have different representations with different media-types -- like your complete user representation might have a media-type application/vnd.mycompany.user.full.v1+json, and a simplified user representation might have a media-type application/vnd.mycompany.user.min.v1+json -- or you can have a single representation like application/vnd.mycompany.user.v1+json and your documentation for this media-type might detail how some properties might exist or not, or might have default values if not provided. Your POST method will require one media-type to work, and will respond with 415 Unsupported Media Type if clients send anything else in the Content-Type header. In the same way, a client may choose the representation it wants with the Accept header.
As you can see, what you are asking isn't a problem when you are really doing REST, and not merely using it as a buzzword for an HTTP API.

How Would You Design a RESTful Conversion Service?

We are creating a service to perform conversions from one format to another. Examples of conversions are currencies, distances, times, languages, etc. In our case it is geographic points (for example from decimal degrees latitude/longitude to degrees-minutes-seconds latitude/longitude).
Typically a RESTful resource has an analogous OO concept that is persistent on the server side that can be CRUDed (I know this is only part of what makes something RESTful), but in the case of a simple service that converts things, that doesn't necessarily exist. How would one make this RESTful? Currently we have some like this:
To get the list of supported formats one can do this:
GET /coordinates/formats
Which would return a list of formats, including, for example DD and DMS (decimal degrees and degrees-minutes-seconds).
One can then turn around and perform a conversion like so:
POST /coordinates/DD/as/DMS
In this example one would pass a representation of decimal degrees (as JSON or some other format) in the request body, and receive a representation of degrees-minutes-seconds in the response body.
This of course works, but feels unRESTful, in particular because the same URI is used over and over for different inputs (different decimal degrees). The trick is probably to really concentrate on what the resource being manipulated it. Perhaps its a "Conversion":
POST /coordinate/conversions
The body might take in the a value, its format, and the desired output. However, the URI is still the same for all resources...
Thoughts?
I would suggest using parameters and GET. I also would switch path elements and make /conversions your root-resource, as conversion is your "domain-core".
Main reasons are:
From api-client perspective above is easier to use (no POST payload, very easy to test/try-out). Client friendliness is one of the highest priorities for api-design.
GET fits better because you don't "change" anything on the server side but rather convert things.
GET /conversions/coordinate?input=xxx&format=yyy
I like your approach to give back metadata with /conversions/formats. It makes formats easy to lookup and your api more self-explainable. The respective data then forms the possible value for 'format'-parameter from above call.
Or are you storing conversion (which would favor state-changing POST method)?