Rest best practices: what standard should I follow? - rest

I read following books and links before I post this question and since this question is about best practices, this question might be closed. However i am expecting some expert views.
https://www.restapitutorial.com/resources.html
REST-API-Design-Rulebook book from oreily
other blogpost and stackoverflow question.
For example to get information about employee with id we are using uri as below
http://myapp-name.myorganization.com/employees/employeeid/123456
But all above resources tell me to do this way
http://myapp-name.myorganization.com/employees/123456
Similarly if i want go get information about employee with id 12345, my uri is as below
http://myapp-name.myorganization.com/countries/country/US/employeeid/12345
as opposed to
http://myapp-name.myorganization.com/countries/US/12345
Does that mean my uri are not standard?

They are just guidelines. You can't cover all kinds of possibilities of your business and necessities on a Rest documentation.
Talking about your examples, the
http://myapp-name.myorganization.com/employees/employeeid/123456
And
http://myapp-name.myorganization.com/employees/123456
Are both correct. But could be better (shorter).
Usually I prefer the second one and use the first one for the alternatives. Per example, if I would like to find an employee by id (the "default" method to find employees) or his unique internal company code, I prefer to use respectively:
/employees/123456 # by id
/employees/code/A899123A # by code
Similarly if i want go get information about employee with id 12345,
my uri is as below
http://myapp-name.myorganization.com/countries/country/US/employeeid/12345
This URL means to me that you trying to find an employee with id 12345 on the US country. But could be shorter too if the US term is the default method to find countries on your API:
/countries/US/employees/12345
as opposed to http://myapp-name.myorganization.com/countries/US/12345
This one seems confuse. Are you trying to find what with id 12345? It's hard to answer only looking for the URL. So, the /countries/US/employees/12345 is more consistent.
If the idea is find the employee on some country with some code, the URL can follow the same pattern: /countries/US/employees/code/A899123A

Does that my uri are not standard?
No, your URI are fine. REST doesn't care what spellings you use for your identifiers, so long as they are consistent with RFC 3986. There's also RFC 7320, which describes "Best Practices" -- but you will probably find that those best practices still leave you with a lot of freedom.
Think "variable names" - various communities will have their own conventions for how variable names should be spelled, but there isn't any standard.
The same holds for identifiers in REST -- they are opaque strings that neither the API consumer nor the client actually need to parse. (Example: when's the last time you actually looked at the URI used when you submit a search to Google?)
Some routing frameworks will be easier to use if you adhere to a particular convention, but that's purely an implementation detail on the server, the client doesn't care.

Related

API naming conventions for list of objects

Basing on the naming conventions found here : https://restfulapi.net/resource-naming/ , I have a particular question to which I can not find an answer.
Taking the example of customers and accounts where sub-collection resource “accounts” of a particular “customer” can be identified using the URN “/customers/{customerId}/accounts” , how do I find accounts for multiple customer IDs? What are the naming conventions for such a case?
Is the only option to use filters? eg: customers/accounts?customerId=12,22
I tend to avoid filters and keep everything as a urn and keep the implementation of the backend system hidden. e.g. this
customers/accounts?customerId=12,22
means the client needs to know that customers are represented in the system by a variable called customerId. Clients shouldn't need to know that. They just need to know that customers have numbers, IMHO anyway.
This answer shows a solution for your situation, which would look like:
customers/accounts/12,22
although to keep it in line with the domain, where customers have ids and associated accounts, it would look like:
customers/12,22/accounts
and your backend framework would give you the list of customer 'numbers' from the url and at that point they become customerIds.
Not all frameworks may support arrays in paths but pick the right tool for the job and you can design your API to be elegant and a good match for your domain.

REST URL naming convention /users/{id}/cars/{carId} vs /cars/{carId}?

I have a simple model
Each Use can have multiple cars
Now when I decide to name the related REST URL naming for Cars service
Initially I suggest to be as the following
GET /cars/{carId}
But when I read about best practices in REST Resource Identifier (URI) Naming
I found that its better to put parent information in the URI as the following
GET /users/{userId}/cars/{carId}
Any one explain to us
Why the second one is the recommended naming
However, I need ONLY a carId to fetch the car
And no need to userId
REST does not care what spelling you use for your identifiers.
/a4e199c3-ea64-4249-96aa-abb71d860a55
Is a perfectly satisfactory REST identifier.
Guidelines such as the one that you linked should be understood a style guide; human readable identifiers that adhere to local spelling conventions are goodness for exactly the same reasons as human readable variable names that adhere to local spelling conventions.
Some URI guidelines advocate convention over configuration -- put broadly, you can simplify your implementations if you choose identifier spellings that allow your framework to deduce where things should live.
when I read about best practices in REST Resource Identifier (URI) Naming
I found that its better to put parent information in the URI
Maybe; part of the problem may be confusing resources with entities. It's an entirely normal thing for one single row in your database to contribute to the representation of many different resources, each of which has its own identifier
/users/:userId/cars/:carId
/cars/:carId
In HTTP, you might even send to the client information that the representation of one of these resources is equivalent to another (see RFC 7231).
The good news: hypermedia clients can deal this sort of thing automatically, because they have built into them awareness of the semantics of links; web aware hypermedia clients (for instance: browsers) will also be able to do the right thing with the meta data.
The bad news: you probably aren't using hypermedia types as your representations, so you won't see those benefits.
IMO, it depends more on the context. Consider the following example:
GET /users/user001/cars/car001
Response:
owner-name, car-license-no, purchase-date, first-owner
Here the response is - car details, specific to a user
GET /cars/car001
Response:
car-model-no, manufacturer, displacement, car-type
Here the response is - car details, specific to the car

REST url proper format

my REST API format:
http://example.com/api/v1.0/products - get all products
http://example.com/api/v1.0/products/3 - get product with id=3
Also, the products can be orginized into a product groups.
What is a proper way to get all product groups according to REST best practices:
http://example.com/api/v1.0/products/groups
or
http://example.com/api/v1.0/productgroups
...
another option ?
I can't agree with Rishabh Soni because http://example.com/api/v1.0/products/groups may lead to ambiguity.
I would put my money on http://example.com/api/v1.0/productgroups or even better http://example.com/api/v1.0/product_groups (better readability).
I've had similar discussion here: Updating RESTful resources against aggregate roots only
Question: About the thing of /products/features or /product-features,
is there any consensus on this? Do you know any good source to ensure
that it's not just a matter of taste?
Answer: I think this is misleading. I would expect to get all features
in all products rather than get all possible features. But, to be
honest, it’s hard to find any source talking directly about this
problem, but there is a bunch of articles where people don’t try to
create nested resources like /products/features, but do this
separately.
So, we can't be sure http://example.com/api/v1.0/products/groups will return all possible groups or just all groups that are connected with all existing products (what about a group that has not been connected with the product yet?).
To avoid this ambiguity, you can add some annotation in documentation. But you can just prepare http://example.com/api/v1.0/product_groups and all is clear.
If you are developing Rest API for your clients than you should not rely on id's. Instead build a meaningful abbreviation and map them to actual id on server side.
If that is not possible, instead of using
http://example.com/api/v1.0/products/3 you can use http://example.com/api/v1.0/products?product_id=3 and then you can provide "product_id" description in the documentation. basically telling the client ways to use product_id.
In short a url must be meaningful and follow a pattern.The variable part must be send by in the url query(part after ? or POST payload)
With this, method to querying the server is also important. If client is trying to get something to the server he should use "GET" http request, similar POST http request if it is uploading new info and "PUT" request if it is updating or creating a new resource.
So by this analogy http://example.com/api/v1.0/products/groups is more appropriate as it is following a pattern(groups in product) while productgroups is more like a keyword with no pattern.
A directory like pattern is more easier to understand. Like in file systems(C:\Program Files\WinRAR), every part gets us to more generalized target.
You can also customize this for specific group- http://example.com/api/v1.0/products/groups?id=3

Rest 'guidelines' make the API design difficult

I am trying to create an API for my Rest services and i am struggling with the design rules that i try to follow. In generally i am trying to follow (among others) these guidelines:
Don't use verbs in the URIs
Don't use query parameters when altering states
Use plural
Don't use camel case
Now, i have to model something like the following:
Get all departments of a company
Get a department of a company
Delete all deprtaments of a company
Delete a department of a company
I am trying something like this:
GET company/departments
GET company/departments/<depName>
DELETE company/departments
DELETE company/departments {body: department name}
The above, follows the guidelines that i have mentioned, but i really don't think that the resulted URIs are good. Especially the fourth, does a different job and has the same URI as the third.
This is a common problem for me, and i encounter it many times when i am designing REST services. The result is that i always break some designing principles to achieve what i want or make uglier URIs (for example: DELETE company/departments/department).
So the actual question is:
In my design, how can i delete a single department with a Restfull-like URI?
A URL consists of several parts:
http://example.com/company/departments/12345?arg1=this&arg2=that
http: is the scheme. //example.com is the host. /company/departments/12345 is the path, ?arg1=this&arg2=that is the query string, consisting of two parameters: arg1 and arg2. There's another aspect, called matrix arguments, which won't be discussed here.
When REST talks about URLs, it refers to the entire thing. Not parts of it. To REST the entire URL is treated as an opaque blob.
That means REST doesn't care about any particular part: the scheme, the host, the path, or the arguments.
ftp://127.0.0.1/E280F814-1524-41D5-8735-43D8414AE242 is a perfectly fine URL as far as REST is concerned.
So as far as REST is concerned, it doesn't give a rip what path you use in your URL or whether you use parameters or not.
That said, the recommendations against parameters in a URL is because sometimes, caches don't cache paramaterized URLs properly. Thus the preference for /company/department/12345 over /company/department?id=12345.
The 12345 in the path is not a parameter. Its the name of the resource. Just like starwars.mp4 above is not a parameter, nor is E280F814-1524-41D5-8735-43D8414AE242. They're just names. The only folks that actually care are people. The computer doesn't care, the internet doesn't care, REST doesn't care. To them, it's just all bits.
So it sounds like a simple miscommunication that you're fighting. Try not to stress over it too much. Too much weight is pressed on URL naming anyway, when it's the resources and their representations that actually matter.
A better design for RESTful URIs is to use an identifier for the resource. In this case the resource is the department.
So your URIs could be like the following:
GET company/departments
GET company/departments/<department-id>
DELETE company/departments
DELETE company/departments/<department-id>
For example...
DELETE company/departments/58491
By using an identifier, rather than the department name, this avoids spaces in your URIs, which is undesirable. By department name, i assume you meant the user friendly display name, such as "Human Capital Management."
I agree. You should use URL like below to delete a department. Such URL identify a department and can be used to execute HTTP operations on it. Don't provide the department id or name within the payload of the request.
DELETE company/departments/58491
The following link could give you some more details about designing a RESTful service: https://templth.wordpress.com/2014/12/15/designing-a-web-api/.
Hope it helps you,
Thierry

RESTful url to GET resource by different fields

Simple question I'm having trouble finding an answer to..
If I have a REST web service, and my design is not using url parameters, how can I specify two different keys to return the same resource by?
Example
I want (and have already implemented)
/Person/{ID}
which returns a person as expected.
Now I also want
/Person/{Name}
which returns a person by name.
Is this the correct RESTful format? Or is it something like:
/Person/Name/{Name}
You should only use one URI to refer to a single resource. Having multiple URIs will only cause confusion. In your example, confusion would arise due to two people having the same name. Which person resource are they referring to then?
That said, you can have multiple URIs refer to a single resource, but for anything other than the "true" URI you should simply redirect the client to the right place using a status code of 301 - Moved Permanently.
Personally, I would never implement a multi-ID scheme or redirection to support it. Pick a single identification scheme and stick with it. The users of your API will thank you.
What you really need to build is a query API, so focus on how you would implement something like a /personFinder resource which could take a name as a parameter and return potentially multiple matching /person/{ID} URIs in the response.
I guess technically you could have both URI's point to the same resource (perhaps with one of them as the canonical resource) but I think you wouldn't want to do this from an implementation perspective. What if there is an overlap between IDs and names?
It sure does seem like a good place to use query parameters, but if you insist on not doing so, perhaps you could do
person/{ID}
and
personByName/{Name}
I generally agree with this answer that for clarity and consistency it'd be best to avoid multiple ids pointing to the same entity.
Sometimes however, such a situation arises naturally. An example I work with is Polish companies, which can be identified by their tax id ('NIP' number) or by their national business registry id ('KRS' number).
In such case, I think one should first add the secondary id as a criterion to the search endpoint. Thus users will be able to "translate" between secondary id and primary id.
However, if users still keep insisting on being able to retrieve an entity directly by the secondary id (as we experienced), one other possibility is to provide a "secret" URL, not described in the documentation, performing such an operation. This can be given to users who made the effort to ask for it, and the potential ambiguity and confusion is then on them, if they decide to use it, not on everyone reading the documentation.
In terms of ambiguity and confusion for the API maintainer, I think this can be kept reasonably minimal with a helper function to immediately detect and translate the secondary id to primary id at the beginning of each relevant API endpoint.
It obviously matters much less than normal what scheme is chosen for the secret URL.