If this Facebook Graph API is restful - rest

Facebook has an API to get your photos:
GET graph.facebook.com
/me/photos
/me/ is a shortcut for the Id of the person logged in. Is that introducing state into the session and therefore is it restful?
Would it not be more restful to do:
/user/1234/photos
and then have some security layer to make sure only users with the appropriate token can access that URL?
https://developers.facebook.com/docs/graph-api/using-graph-api
Noticing some other places use this pattern. For example:
Stripe do this for GET all coupons:
GET https://api.stripe.com/v1/coupons
Paypal do this for all payments:
GET /v1/payments/payment
https://developer.paypal.com/docs/api/payments/

GraphQL is not restful, I tried to sum this up here.
The /me does not necessarily introduce state, because the id for me could be in the headers, so the serverside can still be stateless.
Is that introducing state into the session and therefore is it
restful?
In fact statelessness is a constraint for rest, so you would have to rephrase your question to "... therefore is it not restful"
But REST relies heavily on URIs, so this shortcut circumvents being transparent in the URI, what is not the best idea according to restful principles.

REST IS a concept/approach/way to provide interoperability between computer systems.
REST IS NOT a standard, approved by a committee/organization in terms of strict regulations.
While there are architectural constraints, recommendations, unwritten rules, common solutions, you can't truly affirm this is rest or this is not rest. Everyone design its service as he thinks it's better.
Graph API is not exactly REST, they are a bit just different things/meanings.
Related to FB /me they said:
The /me node is a special endpoint that translates to the user_id of
the person (or the page_id of the Facebook Page) whose access token is
currently being used to make the API calls.
As this URI depends on authenticated user, what's the problem with it?
Related to PayPal, I think You prefer /v1/payments/payment instead of /v1/payments/35/payment, but the same app deployed to another customer will be /v1/payments/69/payment or a logout like /v1/user/35/logout.
It's all about convenience.

Related

Is it legal to have REST resource such as /currentUser in terms of RESTful and stateless?

In terms of RESTful and stateless it's pretty legal to have resource like
/users/123
But, the question is: is it legal to have resource that omits user id and assumes that it's implicitly resolved on the server from the user session? For example:
/loggedUser
That resource would point to /users/123 when user with identifier 123 is authorized.
Picking a resource locator
Using /me, /users/me, /users/myself, /users/current or similar URIs to identify a resource that corresponds to the authenticated user is perfectly fine from a REST perspective. According to Roy Thomas Fielding's dissertation, any information that can be named can be a resource:
5.2.1.1 Resources and Resource Identifiers
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. [...]
When using the URIs mentioned above, you have an identifier for the authenticated user and it will always identify the concept of an authenticated user, regardless of which user is authenticated.
The stateless constraint
The stateless constraint is not related to how your resources are identified. The stateless constraint is about not storing any session state on server side. In this approach, each request from client to server must contain all the necessary information to be understood by the server.
See que following quote from Fielding's dissertation:
5.1.3 Stateless
[...] each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client. [...]
When targeting protected resources that require authentication, for example, every request must contain all necessary data to be properly authenticated/authorized.
A similar question has been answered here and here.
It is OK as long as you use only the data from request (HTTP Headers in your case). In other words, this may work only for users that pass authentication.
Yes.
It is very common for ReST services to make assumption about authorization context.
Though making such a decision will limit usability of that route for users other than the logged on user. For example an admin might need to use that service for a specific user.
A ReST endpoint may even use Claims that exist in the Authorization context. for example return different data for a user that has logged in using certain mechanism.
of all HTTP headers, there are some that are probably not good to be used to tailor the ReST response. for example I will not use the 'referer'.
Make sure you check for any caching strategy you may have before making such design decisions.
It is perfectly legal as long as you keep it stateless. That is, you infer the current user from a security context provided with the HTTP request, usually a token of some kind.
For example, you perform a GET /current-user with an Authentication header containing a JWT token. The server can get most of the user info of the current user from the JWT token and complete with data from the database and retrieve it back to the caller.
I'd also recommend not to use camel case in URIs. It can be a nightmare for devs and some servers are case insensitive.
Beware, if you are holding a server user session, as you imply in your question, your API is already stateful.
As #n00b says, REST isn't a formal standard - and that's probably a good thing.
The original definition comes from Roy Fielding's dissertation. - so if you're doing the things Roy recommends, your design is RESTful. There are a few other things people have added to that - for instance, the Richardson Maturity Model is pretty commonly accepted. There are a few public "standards" documents on the web, e.g. Microsoft's version. I don't think they address this question directly, though.
So, it's up to you - but for what it's worth...
I believe APIs should be consistent and predictable. If I am asking for information about a user, I don't really like that there are two ways of doing it - one by ID, and one using a magic identifier for the current user. I also don't like the idea of introducing the concept of state into the API - by saying "there's an conceptual entity in your API called current user", you are introducing the concept of statefulness, even if you use HTTP headers to manage that.
So, if your RESTful API is designed for use by client application, I think it's reasonable to ask that client to manage state, and carry around the ID for the current user. This also makes your GET requests consistently cacheable - you can theoretically cache /users/123, but you cannot cache /loggedUser.
I believe there is a logical difference with your authentication and authorization action (I've logged in, proven who I am, and therefore got access to specific resources on the system), versus "I am user 123".
The reason you might disagree with this is that it makes your API harder to discover by human beings - someone who is trying to figure out how to get information about the current user has to log in, and then remember their user ID.

REST API user management URIs

I am writing REST APIs in a MEAN application for user management. Although I normally follow best practices for REST APIs, I do have a security concern about exposing too much detail for user accounts API in the URI.
I would prefer not to include the username or account ID as part of the URI when trying to access a specific user account resource:
/api/accounts/:id or /api/accounts/:username
The one alternate approach I have come across is the use of "me" instead of the resource id:
/api/accounts/me
Most of the use cases I have seen only use GET, but I would like to use this for PUT/POST operations as well:
PUT /api/accounts/me/password
{"oldPassword":"xxx", "newPassword":"yyy"}
Do you think this is a good way? Any other ideas?

Restful principles - sending user's identifier in HTTP headers

I'm creating restful api that is used by angular web page. I'm using token based authentication. Server side determines which user sent request based on token value, so I don't have to pass user id on URI. For example, request that returns all orders for logged (with token) user looks like this:
/api/orders
instead of:
/api/users/123/orders
Api is still stateless, but the same URI returns different data depending on headers. Is it consistent with Restful principles?
I think that this suggested API violates the address-ability feature of REST. The address of a resource should be in a form that is visible and readable (and some other things not related to your question...). One of the nice things of nice URIs is that one can link to it easily. Headers are actually hiding the real address of the resource hence making it impossible to link to it. So bottom line I would not go for such an API.

How to make OAuth API Restful

I refer many document for trying making api Restful like below:
GET /user
POST /user
GET /user/123
PUT /user/123
DELETE /uesr/123
But Backend uses OAuth2 token to retrieve user id, it means that Server will know 123 after get token.
I thought it's not a great idea to put token directly in the id place:
GET /user/aweakleknf11123232sadwanawndajkdnamdal
Is any better practice to the restful OAuth2 API?
While designing RESTful api don't think too much about how your url look, rather it is just representation of your resources.
And moreover it is not good idea to expose domain model of your project if your api is public.
If you have gone through Facebook api design you can see that they refer user as
/me?method=GET&format=json&access_token=...
They have abstracted the domain and just sharing self descriptive representation.

Client Facing REST API Authentication

I have seen many different posts regarding different solutions for authenticating a RESTful API and I have some questions, given this current scenario.
I've built a REST API that will allow clients of my software service (we are a B2B company) to access resources programmatically. Now that I've got the API working properly, I'd like to secure it in the most standardized way possible. I need to allow access to certain resources based on the caller of the API. That is to say, not all users of the API can access all resources.
I have URLS available in the following formats:
https://mydomain/api/students
https://mydomain/api/students/s123
https://mydomain/api/students/s123/classes
https://mydomain/api/students/s123/classes/c456
So far I've come up with these possible solutions:
Provide a unique key to each client that they can use to ultimately generate an encrypted token that will be passed as a GET parameter at the end of each REST call to (re)-authenticate every single request. Is this approach too expensive
https://mydomain.com/api/students/s123?token=abc123
Provide a value in the HTTP Authorization Header as seen here. Is this almost the same as #1? (Except I can't paste a URL into the browser) Do people use these headers anymore?
Use OAuth 2 (which I'm still a bit unclear on). Does OAuth 2 actually authenticate the client as a logged in user? And doesn't that go against the spirit of a REST API being stateless? I was hoping OAuth was the proper solution for me (since it's a public standard), but after reading up on it a little bit, I'm not so sure. Is it overkill and/or improper for REST API calls?
My goal is to provide an API that will not have to be changed for each client that wants to consume the API, but rather that I can provide a standard documentation made available to all of our clients.
I'll be happy to post additional details if I've been unclear.
There are 2 type of clients you probably want to prepare your API:
trusted clients - Which are written by you. They can have the username and password of the actual user, and they can send that data to your server with every request, possibly in a HTTP auth header. All you need is an encrypted connection by them.
3rd party clients - Which are written by some random developer. You can register them in your service and add a unique API key to each of them. After that if an user wants to use their services, you have to show her a prompt in which she can allow access to the 3rd party client. After that the 3rd party client will be assigned to the user's account with the given permissions and it will get an user specific access token. So when the client sends its API key and the user specific token along with the request, then it sends the requests in the name of the user.
OAuth can help you to control the second situation.
Your URLs do not have a meaning to the clients. By REST you have to decouple the clients from the URL structure by sending links annotated with semantics (e.g. link relations). So your documentation does not have to contain anything about the URL structure (maybe it can be useful for server side debug, but nothing more). You have to talk about different types of links. By generating these links on server side, you can check the permissions of the actual user (or 3rd party client) and skip the links which she does not have permission to follow.