Designing of REST URL - rest

I have the following problem. Please suggest me the inputs.
I require the list of transactions which can be categorized as
a. Pending/Completed
b. For given account numbers
c. For given customer ids
d. For given categories (category A, Category B) and so on.
Any of these 4 above and all of these are optional.
I am thinking of putting the above 4 options as query param and have a url something like this http://localhost:8080/Transaction/?status=pending&customerid=3,4&category=catA
Is this a Good design for this requirement?
[EDIT]
I do not know if it is good design to pass nouns as query parameters.

As per as REST URI design is concerned, you have to find out the resources first then operations and how they are linked to each other.
Moreover you should use nouns in your URIs, and try to minimize the number of the query parameters.
For this scenario, you basically want to search for transaction based on some conditions, as you have mentioned.
http://localhost:8080/transaction?status=pending&customerid=3,4&category=catA
You are right, but the implementation should split the value of query parameters to extract values.
In a general practice, Consumer,Account can be treated as separate resource.
http://localhost:8080/consumer/{consumerId}/account/{accountNumber}/transaction?status=pending

Related

Describing "greater than"-filters search in a REST API URL?

I'm designing a REST API where the /widgets endpoint can be filtered to only show widgets with a certain number of connections. This seems like a natural design:
/widgets?connections=4
I also want to allow filtering for widgets using lesser than and greater than, however. These URL designs seem wrong as they don't follow the classic query string pattern or appear misleading:
/widgets?connections>2
/widgets?connections=>2
What is the normal way of designing this kind of filter? I also need to be able to combine filters, e.g. "more than two connections and exactly one screen".
I've read this related question: REST URL design for greater than, less than operations, but it is not the same as it relates to pagination and ID, and does not contain a neat answer for combined filters.
REST does not give you an exact solution, it just says that your should use standards to build an uniform interface if there are available standards. If not, then it is up to you, anyways it must be documented for the client developers.
Here what you are doing is developing a complete query language for the URI. It would be good to check what exactly you need, because if there is a query language standard, then supporting it completely is just too much work. Afaik. Odata has something you need and there are other conventions, for example RQL is a very old one. With a little search there are other ones too: w x y z. I guess there are many others too. I would choose one of these and implement only what I need from it or look for an existing implementation.

(Django REST) API design: 1 path with multiple query parameters, or multiple paths?

Suppose we have the books endpoint, at which we can return serialized Book objects. Most of the time, these are books already published (so the future is omitted), and most of the time we will be displaying a Book list belonging to some user. (so the user parameter is mostly present and we mostly filter to books that belong to some user)
Example query:
http://localhost:8000/api/books?future=true
http://localhost:8000/api/books?user=somebody
http://localhost:8000/api/books?future=true&user=somebody
I'm wondering if the above structure looks OK. Other ideas, some seem worse than others, have come to mind. For example, a different optional endpoint/path (instead of the former):
// this makes the least sense to me
http://localhost:8000/api/books/somebody?future=true
I have also contemplated whether getting those books from the users endpoint would make sense:
http://localhost:8000/api/users/somebody/books
http://localhost:8000/api/users/somebody/books?future=true
And then I can also call:
http://localhost:8000/api/users/somebody/settings
Do you agree the second option doesn't make sense?
Can the first and 3rd example live beside each other?
I guess what I'm really asking: should it be possible to reach the same exact resources by two different means in REST design? How do you prefer one over the other? When do you enforce only one? when do you allow both (if at all)?
In this case the API endpoints will be consumed by a future iOS app developed by myself, but I don't think that should be relevant to the question.

REST API URL pattern for path parameters

I am building a Backbone app which displays interactive facsimiles of diagrams from certain technical manuals. Each manual has a number of diagram types (say A-Z), distributed over its pages. Each diagram might occur more than once across the pages, and sometimes a single page might contain more than one instance of a given diagram type.
I have a Django backend serving a REST API which my frontend consumes. What I have been struggling with is the design of the url for the request. I have tried several patterns, none of which satisfy me. My Django model looks something like this:
class Diagram(models.Model):
type = models.CharField(max_length=1)
page = models.IntegerField(default=1)
order = models.IntegerField(default=1)
data = JSONField(default='{}')
The order field relates to a situation where there is more than one instance of the given diagram type on a page. The table for this model is read-only, so I am just doing simple GETs. Users only view one diagram instance at a time. A diagram is selected by type, page, and (where relevant) order. My initial url design was this:
example.org/api/diagrams/A/pages/1/order/2/
Although there is a plurality of diagrams, the diagrams param suggests a collection - but the diagrams don't 'contain' pages. Same with the pages param. Obviously order can only be singular. So perhaps:
example.org/api/diagrams/type=A/page=1/order=2/
Or perhaps just go with query params:
example.org/api/diagrams/?type=A&page=1&order=2
Personally I prefer path parameters, but the main complication of this is that the order param is actually redundant most of the time - there are only a small number of cases of repetition of a diagram on a page (currently I default order to '1', both on the backend and in the request). So perhaps a combination of both path and query parameters:
example.org/api/diagrams/A/page/1/?order=2
Is this a good pattern? Are there other alternatives I could consider?
Edit: After some additional reading (notably the URI Standard) I think the answer is that a path parameter design is suited for a hierarchical structure... which seems intuitive. But I don't have that, so the right candidate is the pure query parameter design. Right?
Could I suggest a different approach? I know, that may not be the answer you are looking for, but instead of trying to publish the exact object model from your code, think about what "kind" of resource the client needs to see and what is it related to.
For example if the client needs to "browse" the diagrams, you could have 2 media-types, one for listing all diagrams, and for a single diagram itself. The URIs could be:
/api/diagrams/ <-- list of all diagrams with titles
/api/diagrams/1 <-- a single diagram
/api/diagrams/2
...
If the client needs to browse per manual per page, then you can offer those too with additional media-types representing a manual (list of pages), and the pages with links to the diagrams that are on it. For example:
/api/manuals <-- list of all manuals
/api/manuals/1 <-- list of pages, maybe a list of all diagrams in manual
/api/manuals/1/page2 <-- list of diagrams on page2
The same for your case about browsing per order and diagram type.
If you only need a "search" API, and not a "browse" API, then the proper solution would be to create a "form" in which you can submit the information (order, type, page, etc.). So that would be 2 media-types, one for the search description, and probably one for diagrams.
The point is, URI should not be fixed if you are trying to create a REST API. The server should provide the URIs to the client (except for the start URI, the search page for example).
This has several advantages, one being that you can control your URIs on the server. You don't have to be RESTful though, if you don't want to, but even then the URI itself does not really matter if you control the client anyway. Neither your approaches is wrong by objective measures.
Sorry if that does not help.:)

REST idiom for a sub-collection?

My understanding of REST (admittedly limited to pretty much the wikipedia page) is that idiom for GETing a collection is ../resource/ and an item is ../resource/itemId.
Is there a standard idiom for GETing for a sub-collection? For example, if the items in the collection have some state toggle (say states A, B, C, D), and I want to be able to ask for items with state B, is there a standard/common/best-practice way to do that?
If not, I'm currently fiddling with the following syntax options:
../resource/B
../resource/state/B
../resource?state=B
What pros/cons of those do you see?
You want to use the third one there, except plural (since you're getting more than one)
../resources?state=B
Because it accurately describe what you want. You're GETing a resource with a specific state.
../resource/B
Would indicate you're getting a specific resource uniquely identified by B
../resource/state/B
Would indicate you're getting a resource state, belonging to resource, uniquely identified by B.
An alternative if you're dealing with a finite number of states would be to make state a resource by itself and make the resource a child of that state. Then you would have
states/B/resources
The REST constraints actually say nothing about how you name resources. REST just says resources should have a name.
Having said that, Jamie's answer is probably the most obvious way of doing it. You can compare naming URLs to naming procedures, there is no right and wrong way to do it, just some names are more obvious than others.

REST best practice for getting a subset list

I read the article at REST - complex applications and it answers some of my questions, but not all.
I am designing my first REST application and need to return "subset" lists to GET requests. Which of the following is more "RESTful"?
/patients;listType=appointments;date=2010-02-22;user_id=1234
or
/patients/appointments-list;date=2010-02-22;user_id=1234
or even
/appointments/2010-02-22/patients;user_id=1234
There will be about a dozen different lists that I need to return. In some of these, there will be several filtering parameters and I don't want to have big 'if' statements in my server code to select the subsets based on which parameters are present. For example, I might need all patients for a specific doctor where the covering doctor is another and the primary doctor is yet another. I could select with
/patients;rounds=true;specific_id=xxxx;covering_id=yyyy;primary_id=zzzz
but that would require complicated branching logic to get the right list, where asking for a specific subset (rounds-list) will achieve that same thing.
Note that I need to use matrix parameters instead of query parameters because I need to do filtering at several levels of the URL. The framework I am using (RestEasy), fully supports matrix parameters.
Ralph,
the particular URI patterns are orthogonal to the question how RESTful your application will be.
What matters with regard to RESTfulness is that the client discovers how to construct the URIs at runtime. This can be achieved either with forms or URI templates. Both hypermedia controls tell the client what parameters can be used and where to put them in the URI.
For this to work RESTfully, client and server must know the possible parameters at design time. This is usually achieved by making them part of the specification of the link relationship.
You might for example define a 'my-subset' link relation to have the meaning of linking to subsets of collections and with it you would define the following parameters:
listType, date, userID.
In a link template that spec could be used as
<link rel="my-subset' template="/{listType}/{date}/patients;user_id={userID}"/>
Note how the actual parameter name in the URI is decoupled from the specified parameter name. The value for userID is late-bound to the URI parameter user_id.
This makes it possible for the URI parameter name to change without affecting the client.
You can look at OpenSearch description documents (http://www.opensearch.org) to see how this is done in practice.
Actually, you should be able to leverage OpenSearch quite a bit for your use case. Especially the ability to predefine queries would allow you to describe particular subsets in your 'forms'.
But see for yourself and then ask back again :-)
Jan
I would recommend that you use this URL structure:
/appointments;user_id=1234;date=2010-02-22
Why? I chose /appointments because it is simple and clear. (If you have more than one kind of appointment, let me know in the comments and I can adjust my answer.) I chose the semicolons because they don't imply hierarchy between user_id and date.
One more thing, there is no reason why you should limit yourself to just one URL. It is just fine to have multiple URL structures that refer to the same resource. So you might also use:
/users/1234/appointments;date=2010-02-22
To return a similar result.
That said, I would not recommend using /dates/2010-02-22/appointments;user_id=1234. Why? I don't think, in practice, that /dates refers to a resource. Date is an attribute of an appointment but is not a noun on its own (i.e. it is not a first-class kind of thing).
I can relate to what David James answered.
The format of your URIs can be like he suggested:
/appointments;user_id=1234;date=2010-02-22
and / or
/users/1234/appointments;date=2010-02-22
while still maintaining the discoverability (at runtime) of your resource's URIs (like Jan Algermissen suggested).