The "right" way to route map a REST API - node.js

Im working on a small node/angular application
A superadmin should be able to create/edit/delete new client accounts, within views delivered directly from the node application.
The clients on the other hand communicate with the backend/database through Angular and a REST API that the node application delivers. The clients need a username/password to login to their account.
Question: I have this route map, is it right of me to think that the :client need to be in the URL of the REST API, so the backend knows which data to fetch?
the : in the url indicates that it's a variable...
Route map Superadmin
/admin/client – POST
/admin/client/:id – GET
/admin/client/:id – PUT
/admin/client/:id – DELETE
/admin/clients – GET
Route map API JSON
/v1/:client/candidate – POST
/v1/:client/candidate/:id – GET
/v1/:client/candidate/:id – PUT
/v1/:client/candidate/:id – DELETE
/v1/:client/candidates – GET
/v1/:client/settings – GET
/v1/:client/settings – PUT

I think this is a little difficult to answer, because it would say one way is "right" and another is "wrong", when really there could be multiple ways of solving this problem. Here's what I would say though, around how you structure the API endpoints.
If we focus on these API endpoints specifically:
/v1/:client/candidate – POST
/v1/:client/candidate/:id – GET
/v1/:client/candidate/:id – PUT
/v1/:client/candidate/:id – DELETE
/v1/:client/candidates – GET
/v1/:client/settings – GET
/v1/:client/settings – PUT
Here we have a set of APIs that allow someone to look up and perform actions on resources for a specific client. In doing this, you've essentially opened this up to allow anyone to access anyone's data (until you add security). Building APIs like this would be more useful for a "superadmin" like you've described in your question, which would need to access multiple client profiles throughout their day. But as you might imagine, you'd need to restrict access to these endpoints to only those who have "superadmin" access OR are in fact the client themselves.
If instead the main use case of these API endpoints was to serve the clients, I would instead remove the :client parameter:
/v1/candidate – POST
/v1/candidate/:id – GET
/v1/candidate/:id – PUT
/v1/candidate/:id – DELETE
/v1/candidates – GET
/v1/settings – GET
/v1/settings – PUT
Since you mentioned that the client would need to login to hit these APIs, you already know who the client is when they make the request. You can instead look up the client from the request, and access these resources based on who is making the call. Personally I think this makes things a little easier to follow, since the request is always asking for my data, rather than some "client's" data, which you then need to verify they have access to.
But again this is all based on how you architect your application, what's the use cases, who is going to be accessing the system, etc. It might make sense to separate out the "superadmin" APIs from the normal "client" APIs like I've described above, or it might be better the keep them all together. The answer will probably end up being which is easier to understand and maintain in the long term.

Related

REST URI's and caching for GET requests when the list to be returned depends on the rights of the user

It is a multi-tenant serverless system.
The system has groups with permissions.
Users derive permissions based on the groups they are in.
If it makes a difference, we are using Cognito for authentication and it is a stateless application.
For example:
GET endpoint for sites (so sites that the logged-in user has access to based on the groups they are in)
GET endpoint for devices (so sites that the logged-in user has access to based on the groups they are in)
In REST APIs. "The idea is that the data returned by an endpoint should depend solely on the parameters passed meaning two different users should receive the same result for the identical request.
"
What should the REST URI look like to ensure the above-stated idea? Since the deciding factor for the list here is "groups" and thus effective permissions, I was thinking we could pass the groups a user in, in the URI in sorted order to leverage caching on GET endpoints as well, Is there a better way to do it?
In REST APIs. "The idea is that the data returned by an endpoint should depend solely on the parameters passed meaning two different users should receive the same result for the identical request. "
No this is not strictly true. It can be a desirable property, but absolutely not needed. In fact, if you build a proper hypermedia REST api, you would likely want to hide links/actions that the current user is not allowed to use.
Furthermore, a cache will never store responses and send to different users if an AUthorization header is present on the request.
Anyway, there could be other reasons to want this.. maybe it's a simpler design for your case, and there is a pretty reasonable solution.
What I'm inferring from your question is that you might have two endpoints:
/sites
/devices
They return different things depending on who's accessing. Instead of using those kind of routes, you could just do:
/user/1234/sites
/user/1234/devices
Now every user has their own separate 'sites' and 'devices' collection. The additional benefit is that if you ever want to let a user find the list of sites or devices from another user, the API is ready to support that.
The idea is that the data returned by an endpoint should depend solely
on the parameters passed
This is called the statelessness constraint, but if you check the parameters always include auth parameters because of this. The idea is keeping the session data on the client side, because managing sessions becomes a problem when you have several million users and multiple servers all around the world. Since the parameters include auth data, the response can depend on this data, so you can use here the exact same endpoints for users with different permissions.
As of the responses you might want to send back hyperlinks, which represent the available operations. The concept is the same here, if the user does not have permission for the actual operation, then they won't get a hyperlink for that operation and in theory they should never get a 403 status either, because you must follow the hyperlinks you got from the service instead of hardcoding URI templates into your client. So you have to handle less errors and junk requests, and another reason here that you can change your URI templates without breaking the clients. This is called hypermedia as the engine of application state, it is part of the uniform interface constraint.

Is there ever a need to have GET request API as POST is better in every way?

So we were starting a new project from scratch and one of the developers suggested why have any GET API requests as POST API's are better in every which way. (At least when using a mobile client)
On further looking into this it does seem POST can do everything GET can do and it can do it better -
slightly more secure as parameters are not in URL
larger limit than GET request
So is there even a single reason to have a GET API ? (This will only be used from a mobile client so browser specific cacheing doesn't affect us)
Is there ever a need to have GET request API as POST is better in every way?
In general, yes. In your specific circumstances -- maybe no.
GET and POST are method tokens.
The request method token is the primary source of request semantics
They are a form of meta data included in the http request so that general purpose components can be aware of the request semantics and contribute constructively.
POST is, in a sense, the wildcard method - it can mean anything. But one of the consequences of this is - because the method has unconstrained semantics, general purpose components can't do anything useful other than pass the request along.
GET, however, has safe semantics (which includes idempotent semantics). Because the request is idempotent, general purpose components know that they can resend a GET request when the server returns no response (ie messages being lost on unreliable transport); general purpose components can know that representations of the resource can be pre-fetched, reducing perceived latency.
You dismissed caching as a concern earlier, but you may want to rethink that - the cache constraint is an important element that helped the web take over the world.
Reducing everything to POST reduces HTTP from an application for transferring documents over a network to dumb transport.
Using HTTP for transport isn't necessarily wrong: Simple Object Access Protocol (SOAP) works that way, as does gRPC. You still get authorization, and conditional requests; features of HTTP that you might otherwise need to roll your own.
You aren't doing REST at that point, but that's OK; not everybody has to.
That doesn’t mean that I think everyone should design their own systems according to the REST architectural style. REST is intended for long-lived network-based applications that span multiple organizations. If you don’t see a need for the constraints, then don’t use them. (Fielding, 2008)

Securely decouple backend and frontend (node.js server)

I've been looking at node.js, REST APIs and WebSockets lately to further my knowledge about backend and frontend web development. Trying to go with best practices I see REST API comes up all the time. Now my problem which I don't seem to understand how to properly solve.
Say for example I'd like to have client / server decoupled and for this I implement a REST API in the backend so that my frontend will access and get data to render. Specific (imaginary) example: lets say I want to build a rental service website. Now I would like to have an endpoint for my frontend to access information about certain products, let's say the number of bikes that have been rented so far. I'd like to be able to show this on my frontend (through the help of the REST API) but I wouldn't like for other people who call this REST API to be able to get the data (because espionage is a serious business and I'd like to keep the evil ones away, yes they can webcrawl but bla bla). So in essence I'd like for the localhost machine to be able to access (part of) the REST API but not anyone else. Things get complicated because I'd also like people to be able to create a user on my website so then I'd like to have other endpoints which can then be accessed without restriction because I'm thinking, what if at some point I'd like to have a mobile app that is integrated with the service. Then it will be unfeasible to restrict all requests to localhost.
How would you architect a secure server / client as this one? Or in your opinion is it not that big of a deal to have the REST API exposed to others (the evil ones)?
The above goes for WebSockets as well. I know REST APIs are all nice and neat but I think the future lies in near-realtime connections and so I'm likewise as interested in WebSockets (through higher level modules of course, Socket.io, SockJS etc.).
There are many solutions to secure your API out there and many of them are opensource. Which one you'll use really depends your detailed needs.
But to get you started I will mention a solution that is very accepted and supported by a large community:
Have a look at JSON Web Token, which are for example explained in this Article.
Basically your client requests an authentication token from the server and then stores it locally to reuse it for every request to your API.
The Server on the other hand may protect your API as needed. That means you may also have a public API that does not expect a token in the HTTP Header.
Tokens may also expire. That is handy if you, for example, will allow a new user for registering on your site for a limited time.
Here is another article that explains things.
Now on to the websocket part of your question. YES, you definetly want to protect your server side sockets as well. So look out for a library that supports authentication. Again, I think there are a number of opensource libraries out there.
To mention one: Primus.
Primus is an abstraction layer for many socket libraries underneath and lets you quickly change the socket provider. But it also has an authentication hook that you can implement.
And guess what.. you can use it to check for a JSON Web Token!
Hope this gets you started.

REST with complex permissions over resources

Background
I'm having a trouble with the design and implementation of a REST service which publishes content that some users cannot view (medical information, you know, country's laws), I'm using a ABAC-like/RBAC system to protect them, but what causes me concern is that I may be violating the REST pattern. My services does the following process for each query:
The security middleware reads a token from a session that an app/webpage sends using authorization header or cookies.
ABAC/RBAC Rules are applied to know if user can access the resource.
After authorize the token, my service executes the query and filters the results, hiding content that requesting user cannot see (if needed. POST, PUT and DELETE operations are almost exempt from this step). The filter is done using ABAC/RBAC rules.
An operation report is stored in logs.
I already know that sessions violates REST pattern, but I can replace it using BASIC/DIGEST authorizations. My real question is the following:
Question
Does hiding resources from list/retrieve operations violates REST pattern? As far I know, REST is stateless, so ... What happens if I use some context variables to filter my results (user id)? Am I violating REST? Not at all?
If I do, What are your recommendations? How can I implement this without breaking REST conventions?
First of all, client-side sessions don't violate REST at all. REST says the communication between client and server must be stateless, or in other words, the server should not require any information not available in the request itself to respond it properly. If the client keeps a session and sends all information needed on every request, it's fine.
As to your question, there's nothing wrong with changing the response based on the authenticated user. REST is an architectural style that attempts to apply the successful design decisions behind the web itself to software development. When you log in to Stack Overflow, what you see as your profile is different from what I see, even though we are both using the same URI, right? That's how REST is supposed to work.
I'd recommend returning status codes 401 (Unauthorized) if the user is not authorized to access a resource. And 404 (Not found) if you cannot confirm that the resource even exists.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4
A GET is meant to return a representation of the resource. Nowhere does it say that you must return everything you know about that resource.
Exactly what representation is returned will depend on the request headers. For example of you might return either JSON or XML depending on what the client requested. Extending this line of thinking; it is ok to return different representations of a resource based on the client's authentication without violating REST principals.

Is it good to use POST for each HTTP verb in REST API for security reasons?

I am working on an enterprise web app. Our app would be deployed to production in https only. We are writing REST APIs that would be consumed by our html 5 client only (not for others)
My team has taken decision to use POST for all rest verbs, because GET, PUT, DELETE exposes id in the url.
What my team thinks is that, having any type of data exposed in the url is not a good idea, even if id is not directly the database id.
Everybody seems to be agreed to use POST http method for GET, PUT, DELETE and pass http_method as parameter and using the parameter decide what operation to do.
This is the only difference that we are planning to do for REST APIs. What do you think?
By avoiding the use of GET you loose the ability to use caching. Hiding the id of the resource in the body will most likely cause you to violate the "identification of resources" constraint. Which will make linking/hypermedia far more difficult.
I would assert that it will be almost impossible to get the benefits of a RESTful system if you limit yourself to POST. Having said that, considering you are only targeting HTML5 clients you probably don't need most of the REST benefits. Doing Json-RPC is probably more than adequate for your needs.
However, I still think throwing away GET for a false sense of security is a bad idea. The body of your posts are just as easy to access by some intermediary as an id in the URI.
You should use HTTP as it was intended so you can get the full benefits of the stack. The different verbs have different semantics for a reason.
You can feel like POST is more secure than GET all you want, but it's a false premise.
Who are you securing this data from? Man in the middle? That's what HTTPS solves.
Are you securing it from your end users? The ones who can download your entire application and study the source code at their leisure whenever they want? Or view the source of a page with a right click and see your payloads laid out in all their glory? Or simply turn the browser debugger on and watch all of your traffic? You're trying to secure it from those people?
POST doesn't hide anything from anybody.
You should probably have a look at this post as it pretty much explains what https does for you. So the question would be: who do you want to protect the URL from? It might be in the browser history or visible to someone standing behind the user, but not to anyone listening on the line.

Resources