user likes in a RESTful API - rest

how do you handle a user 'liking' a post or object in a RESTful API so that they can only like it once? Do you create a many to many relationship and create an endpoint to check if a user liked the object for each object that you load? This seems very request intensive and I'm wondering if there is a better, established solution?

Assuming that the users must be authenticated to perform the request and the request contain all the details to be properly authenticated, you could consider the following approach:
POST /posts/:postid/likes: Records a like for the user in post with the given id.
GET /posts/:postid/likes: Returns a representation of all likes for the post with the given id.
DELETE /posts/:postid/likes/:userid: Deletes a like for the user in the post with the given id.

Related

Http Get vs Http Post to get data, which one is recommended?

recently I come across an issue that I don't know which is a good (standard) way to handle it in REST Api.
The problem is very simple. We all know that in standard REST Api, we use Get request to get data and Post request to send data to server to create/update resources.
For that, if we want to get a list of all users in our application, we would use a GET request with url like this: HTTP GET /users
That's easy right. Let's get to our scenario. Our application allows users to create their own post and people can comment, like, or follow posts created by them or other users. On top of that, we have billions of existing users.
Now, let's say we have a post that has been interacted with thousands of users (popular post) and we want to return that list of users. For this to work, we would at least need to send to server the post Id to look up. Obviously, we do not want to return a list of thousands of users at one time. That would be too much for front end to handle. For that, we would introduce a pagination number and page size to limit the number of users returned. Therefore, on top of the post Id, we will need to send page number and page size as well.
Now, we will have two ways to construct our request:
GET request: /users?postId=123&pageNumber=1&pageSize=10
POST request /users with body request
{
"postId": 123,
"pageNumber": 1,
"pageSize": 10
}
GET seems to be a standard one because it is querying and returning data to front end, but again, the postId is exposed to public.
POST, on the other hand, is a bit more safer since parameters do not store in browser
Which one is the more standard one and recommended in this case ?
Use Get.
What concerns you about the post id appearing in a URL?
If all relevant endpoints are secured, there's nothing a user can do with that id unless authenticated and authorized to perform an action on that post.
Besides, the body of a posted request can be viewed in the browser's dev tools so a post just obfuscates the data a little. It doesn't actually secure it.
Get.
You should Secure the program so that it is not misused.
If you send a post request to get thousand data, your server go down.
you should use get and pagination to get best result.

What's the best, REST-ful way to restrict access to subset of resource?

Let's say I have a rest service with 3 different resources: /libraries, /books and /users. Users belong to libraries, and books belong to libraries. Users should not be able to see books from libraries they don't belong to. After authenticating, every request to the service includes a token with the user id.
What should my request look like if I want to get all of the books I have access to?
1) GET /books
(Api endpoint scopes by the user in the auth endpoint)
2) GET /users/:id/libraries => GET /library/:id/books
Use my user id
Do a separate request for each library the user belongs to
Return a 401 when the user calls GET /books
3) GET /users/current/libraries => GET /library/:id/books
Do not use my user id
Do a separate request for each library the user belongs to
Return a 401 when the user calls GET /books
Well, how about this alternative?
GET /users/{id}/libraries/all/books
It would deliver all books (/books) for all libraries (/libraries/all) of a specific user (/users/{id}) which is more or less exactly what your requirement is.
Some people prefer to shortcut the specific resource identification all (or similar) in which case the call would look like this (goes off the REST guideline):
GET /users/{id}/libraries/books
Regarding the 401 (or possibly a 403) situation: if the {id} is the one related to your authorization token, you just deliver the requested information. If the ID is different, you deliver a 401 (or possibly a 403), while a call like GET /users/{id}/libraries would still result in a normal 200 OK response unless you also disallow querying the library information.

Endpoint to get the currently authenticated Rally user?

I generated an API key for my Rally account. Is there a REST API to retrieve my basic user information, such as name, ObjectID, and ObjectUUID?
Sure, you can just read the /user endpoint and fetch whatever fields you need. This endpoint can both be used to query for multiple users, or if just read without any parameters it will return yourself.
So, to get yourself:
GET https://rally1.rallydev.com/slm/webservice/v2.0/user?fetch=ObjectID
Or to query for users (which you're probably familiar with):
GET https://rally1.rallydev.com/slm/webservice/v2.0/user?fetch=ObjectID&query=(UserName contains "Bob")

One to many relationship in REST design

I have to tables users and teams. The application logic is such that every user should belong to atleast one team(No default here, user can initially belong to any team)
If I am using RESTful APIs to create users resource, should I send the info about user's team in this API itself.
POST /api/users
Or should I make 2 requests
POST /api/users
PUT /api/teams/{id}
If I use the second logic, there is an inconsistency in database if second API is never called.
What is the right thing to do in case of REST design?
What about POST /api/teams/{id}/users.
The URI is self explanatory, you are posting a user directly in a the appropriate team.

POST Request twice

How does doing the same post request twice create duplicate for the same resource.
From what I learnt and understood,
whenever someone does
POST api/users/reg
I must register the user and create the resource URL for the specific user.
Now if someone tries to register with same data on the given api, how is it supposed to create a duplicate resource. It would respond with an error showing that the username is already taken.
Rethink your API design. The resource type users may have many users with unique resource id.
api/users/reg/:userId
This way you can post any number of users given the id is different each time.