REST resources with parameters - rest

Here is a problem. This is our simple domain: there is a number of questions and answers, a question may have several answers or doesn't have any.
Example:
question : "Where can I get a pen?".
answer #1:"You can buy a pen in a shop."
answer #2:"You can borrow it from a friend."
For the following situation it's possible to use the following REST resources:
GET /questions
GET /questions/{question_id}
GET /questions/{question_id}/answers
GET /questions/{question_id}/answers/{answer_id}
However some questions may have parameters like:
"What is the distance between {location A} and {location B}?"
"What is the status of flight {flight_number}?"
What is the best way to represent such questions and answers for them as REST resources?

You can use the following links:
GET /questions/{question_id}/locationA:Zurich/locationB:Budapest/flightNumber:1234/answers
GET /questions/{question_id}/answers?locationA="Zurich"&locationB="Budapest"&flightNumber=1234
Now I am not sure you need the question id here. If there are limited number of question types, then you can add a path for each of them.
GET /questions/distance/from:"Zurich"/to:"Budapest"
You can generate this automatically from the question title:
GET /questions/what-is-the-distance/between:"Zurich"/and:"Budapest"
To be honest the URI structure does not really matter by REST services, because it is used only by machines and maybe by developers to configure the routing. REST clients should follow links instead of building URIs (HATEOAS constraint). So most of the APIs are not REST and most of their clients are not REST clients...

Ok, I think you could build something like this
GET /question /{questionid}?location=a&location2=b
And
GET /question /{questionid}?number=12345
But, it is going to have a lot of things to consider.
Who defines what the parameter names would be? Is it the caller who asks the question? I guess without more of an idea of the actors involved in interacting with these services it is hard to be more specific.
Sorry, this is not as much help as I hoped it would be when I started. :)

What about considering POST as here I understand you are getting the question, but at the same time you are creating a question with filling in the variables.
Provide the variables as a list of Key Value pairs (or Dictionary) in body.

Related

REST: The same resource accessed from two different URLs

I've just started my journey with REST, so please be patient while anserwing my questions.
I have some doubts how to cope with some situations. For instance, I read that evenry resource/entity should have its own, unique URL. But how to deal with examples like:
There is a list of objects.
Each object is described by some basic information and its state.
Basic info for object is for example its shape, color.
The state of object contains information like position in space, velocity etc.
Both two pieces of information (basic + state) are rather big objects (only examplary properties were introduced).
Now, we have the following questions:
Get all basic info about objects.
Get all object states.
Get basic info of object with ID=2.
Get state of object ID=5.
Get all info of object ID=7.
I tried to solve it in this way:
/rest/objects
/rest/states
/rest/objects/2/basic
/rest/objects/5/state (/rest/states/5)
/rest/objects/7
However, I've some doubts pointed in 4 - it doesn't look like to be correct. There are two ways to access the same information/resource/entity.
How to deal with it?
Isn't the "basic" just part of the resource? It seems not from your description, but you should consider it. In fact, all of "basic" and "state" might just be part of the resource. It's difficult to be authoritative without more information. For instance, how large is "rather big"?
It also doesn't seem like /state should be an independent endpoint, since a state is an integral part of an object, not something that lives on its own.
I might start with something like:
1. GET /objects
2. GET /objects?expand=state
3. GET /objects/2?expand=basic -- or -- GET /objects/2/basic
4. GET /objects/5?expand=state -- or -- GET /objects/5/state
5. GET /objects/7?expand=basic,state
If you need /state to be top level, then you have two options:
2. GET /states -- or -- GET /objects/states
Neither of those are really ideal. It is acceptable to have multiple paths to get to the same resource, as long as there's only one canonical URI for the resource. The issue is that it's harder for the end user to learn APIs that lean heavily on that style. The second style is also confusing. /objects/XXX is a specific object, unless XXX == states? That's a special case for your end user to have to remember.
From a caching point of view it makes sense to have "state" and "basic" in separate resources - "state" resources changes frequently and is thus non-cachable and "basic" changes seldom and should thus be cachable for a long time. If this is your goal, then go ahead, it sure makes sense (and is an often mentioned pattern). But usually, to keep complexity low, both sets of values are combined into one single resource (your "Object" in this case).
Your paths are pretty good, Eric's version is also fine - here is my suggestion:
/rest/objects (all complete objects info)
/rest/objects/basic (all basic info)
/rest/objects/state (all state info)
/rest/objects/7 (single complete object)
/rest/objects/2/basic (single basic info)
/rest/objects/5/state (single state info)
In the end it all boils down to a matter of personal preference as the exact URL doesn't matter much.
See for instance http://soabits.blogspot.dk/2013/10/url-structures-and-hyper-media-for-web.html for a longer discussion on this issue (disclaimer: that's my blog).
resource/entity
Don't confuse these concepts. REST has nothing to do how you store your data, and resources map to entities only by CRUD applications.
I read that evenry resource/entity should have its own, unique URL.
You should read the IRI standard. IRIs are for identifying resources. Without them you cannot tell the server what you want to manipulate.
However, I've some doubts pointed in 4 - it doesn't look like to be
correct. There are two ways to access the same
information/resource/entity.
How to deal with it?
It is up to you. You can choose either of them or both. There is no restriction about how many identifiers a resource can have or what IRI structure to choose.

RESTful API subtype in URL, body or header?

I'm somewhat confused about which RESTful design is better.
For the API I have three types; Question, Answer and Student. The Question type has two subtypes; MultipleChoice and Open. The Question type will possibly have more subtypes in the future. Note that the subtypes have common and distinct (optional) properties. Answer is applicable to all questions.
I have seen similar questions (Modeling Object Inheritance in a REST Api, How to model a RESTful API with inheritance?), the given answers point to using a generic URL and specify a type in the body. However I do not feel as if the answers are authoritative (no reference to best practices, not a lot of upvotes, etc).
I'm looking for an authoritative, credible answer based on facts, not opinions.
I'll explain the possible designs below.
Type in URL
Requesting a list of all questions could be possible using GET /questions. This would return a JSON list containing a summary of questions:
[
{
"url": "http://example.com/questions/multiplechoice/1",
"name": "example question"
},
{
"url": "http://example.com/questions/open/2",
"name": "another question"
}
]
Requesting a list of multiple choice questions is possible using GET /questions/multiplechoice.
Creating a new multiple choice question is possible using POST /questions/multiplechoice
Server side these URLs map to different request handlers. The benefit of this is that there is no inspection necessary to check what type is to be created/returned, it is implied in the URL.
The downside of this approach (I think) is that when a student submits an answer the URL would be different for questions. POST /questions/multiplechoice/1/answers and POST /questions/open/2/answers.
Type in body
Requesting a list of all questions stays the same, GET /question. The output would also be the same.
Requesting a list of multiple choice questions would mean filtering so this will be GET /questions?type=multiplechoice.
Creating a new multipe choice question would mean also posting the type. The POST data would be:
{
"type": "multiplechoice",
"name": "example question"
}
The benefit would be that the URL remains simple and is less likely to change in the future. The downside is that one request handler needs to dispatch (using a mapping of some kind) requests based on body to other handlers specific to that type.
Answers are submitted using a universal URL: POST /questions/:question_id/answers
Type in header
The Content-Type and Accept headers can be used instead of the type parameter.
To get a list of all questions: GET /questions.
To get a list of all multiple choice questions: GET /questions, Accept set to application/app.multiplechoice+json.
This approach is similar to the type-in-body approach. The extra downside is that this involves custom mime types, which are not really obvious if you ask me.
MultipleChoice and Open are subtypes of Question. So, there should be urls that contain /question/multiplechoice and /question/open.
About your wish of not receiving answers based on opinions, REST is not a standard, like JEE, nor an implementation, like Spring. It's a style, as baroque or gothic. So, you'll only get opinions as answers.
As per the Rest Api best Practice they given is best practice.In this
the Rest is Resource based as per the standard we should use verb's so i think as per above url your answer is most prply same.
For Get
E.g:- Get/questions/multiplechoice //// this case controller/action/id id(optional)
this route config will resolve this route
Get/questions/open
For post
E.g:- Post/questions/multiplechoice //// you can use same route for post/put/delete.
Post/questions/open

Is using a verb in URL fundamentally incompatible with REST?

So let's say we have something that does not seem best represented as a resource (status of process that we want to pause, stateless calculation we want to perform on the server, etc).
If in API design we use either process/123/pause or calculations/fibonacci -- is that fundamentally incompatible with REST? So far from what I read it does not seem to, as long as these URLs are discoverable using HATEOAS and media types are standardized.
Or should I prefer to put action in the message as answered here?
Note 1:
I do understand that it is possible to rephrase some of my examples in terms of nouns. However I feel that for specific cases nouns do not work as well as verbs do. So I am trying to understand if having those verbs would be immediately unRESTful. And if it is, then why the recommendation is so strict and what benefits I may miss by not following it in those cases.
Note 2:
Answer "REST does not have any constraints on that" would be a valid answer (which would mean that this approach is RESTful). Answers "it depends on who you ask" or "it is a best practice" is not really answering the question. The question assumes concept of REST exist as a well-defined common term two people can use to refer to the same set of constraints. If the assumption itself is incorrect and formal discussion of REST is meaningless, please do say so.
This article has some nice tips: http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
Quoting from the article:
What about actions that don't fit into the world of CRUD operations?
This is where things can get fuzzy. There are a number of approaches:
Restructure the action to appear like a field of a resource. This works if the action doesn't take parameters. For example an activate action could be mapped to a boolean activated field and updated via a PATCH to the resource.
Treat it like a sub-resource with RESTful principles. For example, GitHub's API lets you star a gist with PUT /gists/:id/star and unstar with DELETE /gists/:id/star.
Sometimes you really have no way to map the action to a sensible RESTful structure. For example, a multi-resource search doesn't really
make sense to be applied to a specific resource's endpoint. In this
case, /search would make the most sense even though it isn't a noun.
This is OK - just do what's right from the perspective of the API
consumer and make sure it's documented clearly to avoid confusion.
I personally like suggestion #2. If you need to pause something, what are you pausing? If it's a process with a name, then try this:
/process/{processName}/pause
It's not strictly about nouns vs. verbs; it's about whether you are:
identifying resources
manipulating resources through representations
What's a resource? Fielding defines it thusly:
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. A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time."
Now, to your question. You can't just look at a URL and say, "Is such-and-such a URL fundamentally incompatible with REST?" because URLs in a REST system aren't really the important bit. It's more important that the URLs process/123/pause and calculations/fibonacci identify resources by the above definition. If they do, there isn't a REST constraint violation. If they don't, you're violating the uniform interface constraint of REST. Your example leads me to believe it does not fit the resource definition and therefore would violate this constraint.
To illustrate what a resource might be in this system, you could change the status of a process by POSTing it to the paused-processes resource collection. Though that is perhaps an unusual way of working with processes, it's not fundamentally incompatible with the REST architecture style.
In the case of calculations, the calculations themselves might be the resource and that resource might look like this:
Request:
GET /calculations/5
Response:
{
fibonacci: 5,
prime-number: true,
square-root: 2.23607
}
Though again, that's a somewhat unusual concept of a resource. I suppose a slightly more typical use might look like this:
Request:
GET /stored-calculations/12381728 (note that URL is a random identifier)
Response:
{
number: 5,
fibonacci: 5,
prime-number: true,
square-root: 2.23607
}
though presumably you'd want to store additional information about that resource other than a sheer calculation that anyone can do with a calculator...
Response:
{
number: 5,
fibonacci: 5,
prime-number: true,
square-root: 2.23607,
last-accessed-date: 2013-10-28T00:00:00Z,
number-of-retrievals-of-this-resource: 183
}
It's considered bad practice to use verbs in your REST API.
There's some material on SO and elsewhere on why and how to avoid using verbs. That being said, there are plenty of "REST" APIs that use verbs.
For your process API, I would make the resource Process have a state field, which can be modified with a PUT.
Suppose GET /process/$id currently returns:
{
state: "PAUSED"
}
Then you PUT this to /process/$id:
{
state: "RUNNING"
}
which makes the process change state.
In the case of Fibonacci, just have a resource named fibonacci, and use POST with parameters (say n for the first n fibonacci numbers) in the body, or perhaps even GET with a query in the URL.
The HTTP method is the verb: GET, PUT, POST, et cetera, while the URL should always refer to the noun (recipient of the action). Think of it like this: Would two verbs in a sentence make sense? "GET calculate" is nonsense, where "GET state" is good and "GET process" is better ("state" being metadata for a process).

How an RPC-style example would look modelled in a resource-centric style

I have been reading around the web about REST for several days now and am struggling with the concept of HATEOAS.
I think I am struggling because I don't properly understand how to model data as resources and (state-transitioning?) links between resources. I believe my problem is that all my experience is OO and RPC and I am unused to thinking in a resource-centric manner.
The only way to get an understanding is to take an example from my world, say what I think that might look like modelled in a resource/link-centric manner and throw it out there to be shot down in flames. After the burn is complete I should at least have a better understanding of what I don't understand.
My (simplified) example is:
I am a contractor e.g. a plumber.
I have a number of jobs assigned to me.
I can search my jobs specifying simple paramaters such as a target date range.
I can start any job assigned to me. When I start the job, I can optionally specify the time I started it or leave it blank if I am starting it now.
If I were implementing this in an RPC manner I might expose two methods to callers:
ListOfJobs GetJobs(search parameters)
StartJobResult StartJob(jobID, optional start datetime)
As you can see, I am thinking objects and operations.
If I were thinking resources and links, what might the resources be?
My guess is:
Contractor: ~/contractor/plumbersareus ?
JobSearch: ~/contractor/plumbersareus/searches/searchidentifier ?
Job: ~/job/12345 ?
Attendance: ~/job/12345/attendances/attendanceidentifier ?
Assuming any of the above is correct (and I doubt it is), what should "searchidentifier" and "attendanceidentifier" be? The former wouldn't have an identity in my RPC world; it would just be parameters. The latter would be identified by a DateTime.
What might the links be (ignoring links to self)?
Contractor: ~/contractor/plumbersareus/searches ?
JobSearch: ~/job/12345, ~/job/12346, etc ?
Job: ~/job/12345/attendances ?
Attendance: ?
Please accept my apologies if this a repeat question and close it down. (I couldn't find a repeat but I may have been searching with the incorrect terms.)
You may have read these two great books:
REST in Practice
Restful Web Services
Back to your questions. The more practical way of thinking or applying REST as the starting point (at least it works for me) is to think in the following ways:
1) Use only HTTP ‘GET/POST/PUT/DELETE’ as the way to model your domain ‘actions’ . Just like when you dealing with database, all your actions are mapped to CURD.
2) URI/URL is to identify resources only. Should never have any ‘actions’ in your URI.
3) The data exchanged should be in the body of the HTTP messages.
Just to simplify the discussions, not getting into how to model the data itself
Here is what comes to my mind. I’m sure that there are better ways to model what you have but it should be around the same principles☺ E.g. how the URL patterns look like is all depending on your application domain and what makes sense between the client and the backend.
To model ‘get jobs’:
HTTP: GET
URL: ~/contractors/[plumberID]/jobs/
To model, job search:
HTTP: GET
URL: ~/jobs/?[some search params]/
To model assign the job to user:
HTTP: PUT
URL: ~/contractors/[plumberID]/assignments/[jobID]
There are some differences in using PUT vs POST, you can search around.
Hope this help.

Are there any naming convention guidelines for REST APIs? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
When creating REST APIs, are there any guidelines or defacto standards for naming conventions within the API (eg: URL endpoint path components, querystring parameters)? Are camel caps the norm, or underscores? others?
For example:
api.service.com/helloWorld/userId/x
or
api.service.com/hello_world/user_id/x
Note: This is not a question of RESTful API design, rather the naming convention guidelines to use for the eventual path components and/or query string parameters used.
Any guidelines would be appreciated.
I think you should avoid camel caps. The norm is to use lower case letters. I would also avoid underscores and use dashes instead
So your URL should look like this (ignoring the design issues as you requested :-))
api.service.com/hello-world/user-id/x
The REST API for Dropbox, Twitter, Google Web Services and Facebook all uses underscores.
Look closely at URI's for ordinary web resources. Those are your template. Think of directory trees; use simple Linux-like file and directory names.
HelloWorld isn't a really good class of resources. It doesn't appear to be a "thing". It might be, but it isn't very noun-like. A greeting is a thing.
user-id might be a noun that you're fetching. It's doubtful, however, that the result of your request is only a user_id. It's much more likely that the result of the request is a User. Therefore, user is the noun you're fetching
www.example.com/greeting/user/x/
Makes sense to me. Focus on making your REST request a kind of noun phrase -- a path through a hierarchy (or taxonomy, or directory). Use the simplest nouns possible, avoiding noun phrases if possible.
Generally, compound noun phrases usually mean another step in your hierarchy. So you don't have /hello-world/user/ and /hello-universe/user/. You have /hello/world/user/ and hello/universe/user/. Or possibly /world/hello/user/ and /universe/hello/user/.
The point is to provide a navigation path among resources.
'UserId' is wholly the wrong approach. The Verb (HTTP Methods) and Noun approach is what Roy Fielding meant for The REST architecture. The Nouns are either:
A Collection of things
A thing
One good naming convention is:
[POST or Create](To the *collection*)
sub.domain.tld/class_name.{media_type}
[GET or Read](of *one* thing)
sub.domain.tld/class_name/id_value.{media_type}
[PUT or Update](of *one* thing)
sub.domain.tld/class_name/id_value.{media_type}
[DELETE](of *one* thing)
sub.domain.tld/class_name/id_value.{media_type}
[GET or Search](of a *collection*, FRIENDLY URL)
sub.domain.tld/class_name.{media_type}/{var}/{value}/{more-var-value-pairs}
[GET or Search](of a *collection*, Normal URL)
sub.domain.tld/class_name.{media_type}?var=value&more-var-value-pairs
Where {media_type} is one of: json, xml, rss, pdf, png, even html.
It is possible to distinguish the collection by adding an 's' at the end, like:
'users.json' *collection of things*
'user/id_value.json' *single thing*
But this means you have to keep track of where you have put the 's' and where you haven't. Plus half the planet (Asians for starters)
speaks languages without explicit plurals so the URL is less friendly to them.
No. REST has nothing to do with URI naming conventions. If you include these conventions as part of your API, out-of-band, instead of only via hypertext, then your API is not RESTful.
For more information, see http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
Domain names are not case sensitive but the rest of the URI certainly can be. It's a big mistake to assume URIs are not case sensitive.
I have a list of guidelines at http://soaprobe.blogspot.co.uk/2012/10/soa-rest-service-naming-guideline.html which we have used in prod. Guidelines are always debatable... I think consistency is sometimes more important than getting things perfect (if there is such a thing).
If you authenticate your clients with Oauth2 I think you will need underscore for at least two of your parameter names:
client_id
client_secret
I have used camelCase in my (not yet published) REST API. While writing the API documentation I have been thinking of changing everything to snake_case so I don't have to explain why the Oauth params are snake_case while other params are not.
See: https://www.rfc-editor.org/rfc/rfc6749
I don't think the camel case is the issue in that example, but I imagine a more RESTful naming convention for the above example would be:
api.service.com/helloWorld/userId/x
rather then making userId a query parameter (which is perfectly legal) my example denotes that resource in, IMO, a more RESTful way.
I would say that it's preferable to use as few special characters as possible in REST URLs. One of the benefits of REST is that it makes the "interface" for a service easy to read. Camel case or Pascal case is probably good for the resource names (Users or users). I don't think there are really any hard standards around REST.
Also, I think Gandalf is right, it's usually cleaner in REST to not use query string parameters, but instead create paths that define which resources you want to deal with.
http://api.example.com/HelloWorld/Users/12345/Order/3/etc