How should REST API accept boolean values? - rest

Resource 123 has a current configuration state and a default configuration state, and both of these configuration states can be represented by JSON.
A GET request to http://example.com/123/config will return the current configuration state, and a GET request to http://example.com/123/config?reset=true will return the default configuration state.
How should an API interpret boolean values? For instance:
http://example.com/123/config?reset=true
http://example.com/123/config?reset=blablabla
http://example.com/123/config?reset=false
http://example.com/123/config?reset=1
http://example.com/123/config?reset=0
http://example.com/123/config?reset=
http://example.com/123/config?reset

True and false
The true and false literals are just fine to represent boolean values. They are quite descriptive and, if your API supports JSON, true and false are definitively the obvious choices.
Enumerations
In a few situations, however, you may want to avoid boolean values because they cannot be expanded. You may want to consider enumerations instead.
It may be a poor comparison but it might help you to get the main idea of this approach: have a look at CSS properties such as overflow or visibility. They allow expandable values instead of only true or false. So new values can be easily added without changing the property names.
So, for the situation described in your question, to retrieve the default state of a resource, I would support a query parameter such as status, that could have values such as default and current.
The following would return the default state of the resource:
GET /config?status=default HTTP/1.1
Host: example.com
Accept: application/json
And the following would return the current state of the resource:
GET /config?status=current HTTP/1.1
Host: example.com
Accept: application/json
If no query parameter is provided, you could that the client wants the current state of the resource.
If you need to restore the resource state to its default state, consider using PUT, sending the new representation of the resource in the request payload. Something like:
PUT /config/status HTTP/1.1
Host: example.com
Content-Type: application/json
{
"value": "default"
}

Whichever way you want it to, it's completely up to you as the architect/designer. true/false is the most syntactically correct version, make sure that one works and add the other options as sugar if you want.

Related

REST API - what to return when query for a GET does not find a result

I'm calling a backend REST endpoint that takes in a query param and searches for a matching result /people?name=joe, and I'm wondering what status code and return data I should be returning when no object is found in the DB matching name=joe.
Things I've considered:
If I was directly hitting an endpoint /people/joe and it was not found, then I would definitely return 404.
If I was hitting an endpoint that returned a list of results for a query like if /people?name=joe was supposed to return ALL people named joe, then I would just return 200 with an empty list as the body. But in my case, I can only have one object for each name, so I'm not returning a list, so this doesn't apply here.
So this is a different case where I'm hitting an endpoint and passing in a query param to "search" for some data. And it is expected that in many cases, the data won't exist yet.
This seems pretty similar to the first bullet point above, but I don't like returning a 404 here since this is not necessarily an error.
Should I return a 200 but with an empty object {} as the body, and then my frontend should check if body == {} then take that to mean no data found?
Or should I still return a 404 here? Again, this is not really an error in my case which is why I don't want to use a 404, but if that makes most sense, then I could.
Easy parts first - status codes are metadata of the transfer-of-documents-over-a-network domain (Webber, 2011). In the context of a GET request (which asks for the current selected representation of a resource), a 200 response indicates that the response content is a representation of the resource (as opposed, for example, to being a representation of an error).
Furthermore, URI are opaque: general purpose HTTP components do not make assumptions about the semantics of resources based on the spelling of their identifiers. In other words, the "rules" are exactly the same for both
/people/joe
/people?joe
/people?name=joe
...
So at the HTTP level, the answers to your question are easy: if there's a current representation, then you reply to GET requests with a 200 status and copy the current representation into the response content.
The hard parts are deciding when there is a current representation, and what it looks like. REST and HTTP don't have anything to say about that, really. It's a resource design concern.
For example, this is interaction "follows all the rules":
GET /people?name=dave HTTP/1.1
HTTP/1.1 200 OK
Content-Location: /people?name=dave
Content-Type: text/plain
Dave's not here, man
HTTP is a general purpose mechanism for asking for documents/transmitting documents over a network, but it is agnostic about what documents look like and what keys we use to identify documents in the store.
If you are dealing with representations that describe zero or exactly one things, it can still be reasonable to use a list which is either empty or contains exactly one element (if you are familiar with Option/Optional/Maybe: same idea, we're presenting something with the semantics of an iterable collection)
HTTP/1.1 200 OK
Content-Location: /people?name=dave
Content-Type: application/json
[]
HTTP/1.1 200 OK
Content-Location: /people?name=bob
Content-Type: application/json
[{
...
}]
I agree that 200 and empty collection is better than 404 in your scenario. I don't like the idea of looking for {}, it is not explicit enough.
Possible ways of doing this:
200 ok
{
items:[]
}
200 ok
{
size:0//,
//items:undefined
}
200 ok
[]
206 Partial Content
Accept-Ranges: items
Content-Range: items 0-0/0
// []

RestAPI naming convention for boolean endpoints

It is a trivial question but I cannot find an answer. Lets say I have an endpoint that simply checks if a user exists within a certain group and returns a boolean. What should the RestAPI path look like?
/api/user/{id}/exists/{group}
/api/user/{id}/in/{group}
/api/user/{id}/is_assigned/{group}
/api/user/{id}/exists_within/{group}
I feel like the API path name should read organically, but I also don't like using an underscore. What do you guys suggest?
REST doesn't care what spellings you use for your identifiers.
PUT /abff1822-71aa-4147-9b91-18a8a4f1bf6c
Content-Type: application/json
true
PUT /abff1822-71aa-4147-9b91-18a8a4f1bf6c
Content-Type: application/json
false
GET /abff1822-71aa-4147-9b91-18a8a4f1bf6c
Old school POST also "just works"
POST /abff1822-71aa-4147-9b91-18a8a4f1bf6c
Content-Type:application/x-www-form-urlencoded
value=true
URI are a lot like variable names - the machines don't care, and because they don't care you can follow whatever local spelling conventions make sense.

REST Api naming convention?

I have a simple question that I cannot find the answer to.
My colleague is currently making a REST Api for an application, and we have a call that simply checks some information, and returns either true or false. However, we do not know what to call this type of request, as it does not retrive any resources or insert anyhing, it simply checks some information passed into the query. As far as I can understand, a GET has to retrive a resource, which this call isn't doing
What I understand is, resource in this case is either true or false. While calling the API you will expect response either true or false on the basis of information processed by API server (status will be always 200). So a GET method is still suitable for this case.
If you are not interested in response body and you want data like response code and header details, go with HEAD.
There might be a different way to express 'checking some information', and it's important to be a bit more specific as to what that means.
So lets take an arbitrary example. You're modelling blog posts and want to know if some blog post is set to 'draft'.
The 'draft' status can be its own resource, for example:
/posts/hello-world/is-draft
Doing a GET request on the is-draft resource can yield:
{
"is-draft": true
}
So to model arbitrary things as resources, the best way to think about this is to look at the result of the operation as the 'representation' and the 'thing you want to know' as the URI.
As far as I can understand, a GET has to retrive a resource, which this call isn't doing
Technically, it is retrieving a resource; see Fielding
The key abstraction of information in REST is a resource. Any information that can be named can be a resource: a document or image, a temporal service (e.g. "today's weather in Los Angeles"), a collection of other resources, a non-virtual object (e.g. a person), and so on. In other words, any concept that might be the target of an author's hypertext reference must fit within the definition of a resource.
The resource, in this case, might not load an entity in your data model, but that's OK. Not all resources have to.
Technically, I think what you have there is a "function"; all of the information that you need to compute the result is present within the URI itself? Which would mean that, if the client knew how to do the computation (and had the compute resources available), then the client would be capable of doing the work for itself.
But there's nothing wrong with having a resource that is "the result of a function".
In some API, you'll see predicates (functions that return true/false) implemented as resources that only exist (more precisely, only have "representations") if the evaluation is true.
GET /predicate?true
204 No Content
GET /predicate?false
404 Not Found
The fact that you don't need to consider the resources "state" to compute the correct response to the query is an implementation detail hidden behind the uniform interface.
It's hard to tell by the level of details you provided your question. But if you need to check whether a resource exists or not, you can use HEAD. It's identical to GET, but it doesn't return a representation in the response payload: it returns just the status code and the response headers.
Consider the following request HEAD request:
HEAD /postal-codes/10001 HTTP/1.1
Host: example.org
Content-Type: application/json
It should return 200 for a resource that exists:
HTTP/1.1 200 OK
Content-Type: application/json
And 404 for a resource that doesn't exists:
HTTP/1.1 404 Not Found
Content-Type: application/json
Depending on your needs, you could address it with POST, which can be seen as a catch all verb.
For example, consider the following request and responses:
POST /postal-codes/validation HTTP/1.1
Host: example.org
Content-Type: application/json
{ "postal-code": "10001" }
HTTP/1.1 200 OK
Content-Type: application/json
{ "postal-code": "10001", "status": "valid" }
HTTP/1.1 200 OK
Content-Type: application/json
{ "postal-code": "10001", "status": "invalid" }

What is the proper content type for one-word boolean REST resource?

I'm building an API, and for the most part there will be JSON and HTML content there. But a few very specific endpoints only render true or false, and also accept true or false in POST. That is the entire body of the request or response.
What would be the correct content-type header for this resource?
I'm using text/plain. application/text also sounds ok, though it I haven't found it used anywhere else (is it?)
The single words true or false are valid JSON so may use application/json with these values.
However, it is recommended that your JSON messages be either an object or an array as some software may not work properly if this is not the case. To follow that recommendation you might instead return a value such as
{"result":true}

Is there any resource that explains everything about the PUT, POST, DELETE operation in WCF Data Services?

Every single resource I'va come across on Internet always describes very well what you can do with the GET operation, how it works and so on, bu it never explains the POST/PUT/DELETE and particularly the format of the data you pass in the HTTP body (I'm using JSON). It always says "you can make a post request and pass the appropriate data in the body".
I am struggling with what I can do and not. For example I want to know if it is possible to update one field of one entry by just sending the updated value, and not the entire object.
Is there any document that explains clearly the possibilities and limitations?
Thanks a lot.
Easy to read documentation is here: http://www.odata.org/developers/protocols
If you want all the dirty details and a strict language you can read this document: http://msdn.microsoft.com/en-us/library/dd541188(PROT.10).aspx
You can modify a value of a single property by sending a PUT request.
For example if you send a GET to this URL:
http://services.odata.org/(S(kupqbta5wqnfz2cln1qk052x))/OData/OData.svc/Products(0)/Name
And you request JSON (through an Accept header) the response will be:
{
"d" : {
"Name": "Bread"
}
}
The "d" wrapper is there only to avoid XSS attacks so that must not be included in the requests, but the rest stays the same, so if you then send a PUT request like this:
PUT http://services.odata.org/(S(kupqbta5wqnfz2cln1qk052x))/OData/OData.svc/Products(0)/Name HTTP/1.1
Host: services.odata.org
Content-Type: application/json
Content-Length: 20
{
"Name": "Meat"
}
It will update the property Name to value Meat. You can also send a PUT to the value itself, in which case the URL would end with $value (denotes the raw value of the property) like this:
PUT http://services.odata.org/(S(kupqbta5wqnfz2cln1qk052x))/OData/OData.svc/Products(0)/Name/$value HTTP/1.1
Host: services.odata.org
Content-Type: text/plain
Content-Length: 4
Meat
Note that this only works on primitive properties though.
The sample service on the odata.org allows you to make modifications (guarded by the session key in the URL), so can play with it there.
Google for the HTTP 1.1 specification.