REST API design - best practice: Link existing child resource [closed] - web-services

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
When designing a REST API I understand how entities can be added (POST), updated (PUT, PATCH) and so on. But I’m wondering how to design the endpoint to add existing items to an existing resource?
Here’s an example: Let’s assume we have an API with the resources Course and Student and following endpoints:
http://localhost/students - POST to add a new student
http://localhost/courses - POST to add a new course
http://localhost/courses/1 - PUT to update course with Id 1
http://localhost/courses/1/students - GET to list all students from course with Id 1
http://localhost/courses/1/students - POST to add a new student to the course with Id 1
The question is, how can I link an existing student to an existing course? To clarify: With "existing" I'm referring to resources that are already in the system, but are not yet linked.
I see following options:
http://localhost/courses/1/students - PUT and send the student Id in the body. The arguments to use PUT would be that I am "updating" the students resources of the course.
http://localhost/courses/1/students - POST and send the student Id in the body. The reason to use POST is that I am "adding/creating" a new resource in the course.
http://localhost/courses/1/students/2 - PUT and send the Id in the URL and nothing in the body.
http://localhost/courses/1/students/2 - POST and send the Id in the URL and nothing in the body.
http://localhost/students/2 - PUT or POST and send the course Id in the body.
http://localhost/students/2/courses/ - PUT or POST and send the course Id in the body.
...
Are there best practices? Any recommendations? Should this be handled via the courses or the students resource? Should both be possible? Additionally I'm not sure which method to use (PUT or POST)?
It kind of feels weird to PUT or POST with nothing in the body. On the other hand, if everything that is in the body is an Id, why not just put it in the URL?

I think the key is here:
http://localhost/courses/1/students - POST to add a new student to the
course with Id 1
Given that you're using POST on this URL to generically register students into a course, it shouldn't matter whether the student is new or existing. As you said, that can be an implementation detail, like sending the existing student's ID in the body.

The question is, how can I link an existing student to an existing course?
How would you do it as a web site?
The consumer would land on their bookmarked page, and would look around for a link that would say something like "enroll student". They would follow that link to a form, or a series of forms, that would collect the input data (an identifier for the student, an identifier for the course, and so on). Then the consumer would submit the form with the required information.
When the web server received the form submitted in the last step, it would update the domain model as a side effect.
Viewed this way, the "resource" isn't the student, or the course, but is the inbox for enroll student requests.
Jim Webber, from his talk on REST and Domain Driven Design:
The web is not your domain, it's a document management system. All the HTTP verbs apply to the document management domain. URIs do NOT map onto domain objects - that violates encapsulation. Work (ex: issuing commands to the domain model) is a side effect of managing resources.
You POST a message to the inbox resource, and as a side effect whatever necessary changes to student or course, happen in your domain.
So the approach you should take to designing URI is;
imagine the design of the web site, and the protocol that the consumer would use to interact with it
figure out the semantics of each stage of the protocol
apply your local URI spelling conventions to that semantic, to determine the identifier for each resource

Related

Designing RESTful API for Invoking process methods

I would like to know how do design the RESTful web service for process methods. For example I want to make a REST Api for ProcessPayroll for given employee id. Since ProcessPayroll is time consuming job, I don't need any response from the method call but just want to invoke the ProcessPayroll method asynchronously and return. I can't use ProcessPayroll in the URL since it is not a resource and it is not a verb. So I thought that, I can go with the below approach
Request 1
http://www.example.com/payroll/v1.0/payroll_processor POST
body
{
"employee" : "123"
}
Request 2
http://www.example.com/payroll/v1.0/payroll_processor?employee=123 GET
Which one of the above approach is correct one? Is there any Restful API Design guidelines to make a Restful service for process methods and functions?
Which one of the above approach is correct one?
Of the two, POST is closest.
The problem with using GET /mumble is that the specification of the GET method restricts its use to operations that are "safe"; which is to say that they don't change the resource in any way. In other words, GET promises that a resource can be pre-fetched, just in case it is needed, by the user agent and the caches along the way.
Is there any Restful API Design guidelines to make a Restful service for process methods and functions?
Jim Webber has a bunch of articles and talks that discuss this sort of thing. Start with How to GET a cup of coffee.
But the rough plot is that your REST api acts as an integration component between the process and the consumer. The protocol is implemented as the manipulation of one or more resources.
So you have some known bookmark that tells you how to submit a payroll request (think web form), and when you submit that request (typically POST, sometimes PUT, details not immediately important) the resource that handles it as a side effect (1) starts an instance of ProcessPayroll from the data in your message, (2) maps that instance to a new resource in its namespace and (3) redirects you to the resource that tracks your payroll instance.
In a simple web api, you just keep refreshing your copy of this new resource to get updates. In a REST api, that resource will be returning a hypermedia representation of the resource that describes what actions are available.
As Webber says, HTTP is a document transport application. Your web api handles document requests, and as a side effect of that handling interacts with your domain application protocol. In other words, a lot of the resources are just messages....
We've come up with the similar solution in my project, so don't blame if my opinion is wrong - I just want to share our experience.
What concerns the resource itself - I'd suggest something like
http://www.example.com/payroll/v1.0/payrollRequest POST
As the job is supposed to be run at the background, the api call should return Accepted (202) http code. That tells the user that the operation will take a lot time. However you should return a payrollRequestId unique identifier (Guid for example) to allow users to get the posted resource later on by calling:
http://www.example.com/payroll/v1.0/payrollRequest/{payrollRequestId} GET
Hope this helps
You decide the post and get on the basis of the API work-
If your Rest API create any new in row DB(means new resource in DB) , then you have to go for POST. In your case if your payroll process method create any resource then you have to choose to POST
If your Rest API do both, create and update the resources. Means ,if your payroll method process the data and update it and create a new data , then go for PUT
If your Rest API just read the data, go for GET. But as I think from your question your payroll method not send any data.So GET is not best for your case.
As I think your payroll method is doing both thing.
Process the data , means updating the data and
Create new Data , means creating the new row in DB
NOTE - One more thing , the PUT is idempotent and POST is not.Follow the link PUT vs POST in REST
So, you have to go for PUT method.

How to realize modifying call in REST API

Assume you have some resource behind a REST API. This resource could well be modified using the usual HTTP verbs PUT or PATCH. But let's assume the server behind the API has to check some prerequisites to decide if the modification on the resource can be made or not (e.g. withdraw an amount from a bank account).
In this case there is no use in using POST (because we do not want to add a new resource), nor PUT or PATCH, because only the server knows about the new value of the resources' modified attribute, if he will allow the requested modification at all. In the above example the account's new balance would have to be computed on the server side like so : balance = balance - amount, and to my knowledge all the client can do with PUT or PATCH is to send the already modified resource (the account) or atttribute of that resource (the accounts' balance).
Am I then right in assuming that in this case the API designer has to provide a parameter (e.g. .../account?withdraw=amount) with the URL pointing to the resource ? What would be the correct HTTP verb for this operation ?
there is no use in using POST (because we do not want to add a new resource)
You do. A monetary exchange can be expressed in a transaction, hence: you're creating a new transaction.
So simply perform a POST with the transaction details to a /transaction endpoint.
You certainly don't want to allow users to PUT their new account balance, as that would require atomicity over HTTP, which is all REST stands against: the client would have to know the pre-transaction balance, and make sure in some way no transaction will be carried out before theirs arrives.

What exatly is a REST resource and a representation?

I am very new in RESTful application and I have some doubts related to some REST concept.
I know that the fundamental concept in any RESTful API is the resource. A resource is an object with a type, associated data, relationships to other resources, and a set of methods that operate on it (the HTTP methods: GET, POST, PUT and DELETE)
So my first doubt is related to the resource concept. I am trying to do myself some example and I don't know if I have correctly understand what a resource is.
In my mind a resource is "what I have to transmit with my REST web sercice". So for example if I have a REST web service that given a VAT number come backs the invoices related to this VAT number. So these returned invoices "objects" are my resources.
So a resource is something that I can working on: I can obtain an existing reourcem add a new resource, update an existing resource or delete an existing resource.
Is it correct or am I missing something?
If it correct the second doubt is on the representation concept.
From what I have understand I can see a resource in serveral differents shapes (or a resource can be exposed in several different ways), for example as HTML or as XML or as JSON and so on.
So the same resource can be exposed in different ways and exist a mecchanism that convert a resource (that can be a row stored into a database table) into an HTML message or into an XML message or into a JSON message.
Is this interpratation correct?
From this paragraph (emphasys mine):
In my mind a resource is "what I have to transmit with my REST web sercice". So for example if I have a REST web service that given a VAT number come backs the invoices related to this VAT number. So these returned invoices "objects" are my resources.
You got it wrong. By reviewing the concept of a resource (stated in your question, emphasys mine):
A resource is an object with a type, associated data, relationships to other resources, and a set of methods that operate on it (the HTTP methods: GET, POST, PUT and DELETE)
From your example, the invoices objects don't have any set of methods that operate them. They are part of the response of the REST service. Instead, the component (that may be a Java or a C# class) that has a method to receive the VAT number and will return the invoices associated to the VAT number and that will be called to support the proper HTTP method (in this case, GET) is the resource.
Now, after understanding this, there's this other paragraph:
From what I have understand I can see a resource in serveral differents shapes (or a resource can be exposed in several different ways), for example as HTML or as XML or as JSON and so on.
The resource will return the response in the proper format: HTML, XML, JSON, plain text, ect. Again, your invoices are not the resource, and they should not choose the format they should be returned.

Use persistent cookie to subscribe to an eventsource?

In this question Worklight: Push notification without User ID, the given answer was to subscribe a persistent cookie userID with the event source.. my question is: How can I do this? how can I use the userID given by the cookie ( I already got the userID ) to subscribe to my eventSource? Can't seem to find this anywhere on the internet
There is are additional questions you need to ask yourself, before looking into what you wrote.
Are you using Worklight 6.2 or above?
Are you looking to send generic information (i.e. not sensitive, per-user data (like bank account balance and the like))?
If the answer is 'yes' for both of the above, do not bother yourself with event source-based notifications. Instead, use either broadcast or tag-based notifications (tags = "topics of interest"). Using this approach does not require any additional work on your part other than actually sending the notification.
You can take a look at the documentation:
Developer Center: https://developer.ibm.com/mobilefirstplatform/documentation/getting-started-6-3/notifications/push-notifications-hybrid-applications/
Knowledge Center: http://www-01.ibm.com/support/knowledgecenter/SSHS8R_6.3.0/com.ibm.worklight.dev.doc/devref/t_tag-based_notifications_setting_up.html
In the following answer you can find an example for broadcast notifications (broadcast notification is a form of tag-based notifications): https://stackoverflow.com/a/27881423/1530814

How to avoid sending 2 duplicate POST requests to a webservice

I send a POST request to create an object. That object is created successfully on the server, but I cannot receive the response (dropped somewhere), so I try to send the POST request again (and again). The result is there are many duplicated objects on the server side.
What is the official way to handle that issue? I think it is a very common problem, but I don't know its exact name, so cannot google it. Thanks.
In REST terminology, which is how interfaces where POST is used to create an object (and PUT to modify, DELETE to delete and GET to retrieve) are called, the POST operation is attributed un-'safe' and non-'idempotent, because the second operation of every other type of petition has no effect in the collection of objects.
I doubt there is an "official" way to deal with this, but there are probably some design patterns to deal with it. For example, these two alternatives may solve this problem in certain scenarios:
Objects have unicity constraints. For example, a record that stores a unique username cannot be duplicated, since the database will reject it.
Issue an one-time use token to each client before it makes the POST request, usually when the client loads the page with the input form. The first POST creates an object and marks the token as used. The second POST will see that the token is already used and you can answer with a "Yes, yes, ok, ok!" error or success message.
Useful link where you can read more about REST.
It is unreliable to fix these issues on the client only.
In my experience, RESTful services with lots of traffic are bound to receive duplicate incoming POST requests unintentionally - e.g. sometimes a user will click 'Signup' and two requests will be sent simultaneously; this should be expected and handled by your backend service.
When this happens, two identical users will be created even if you check for uniqueness on the User model. This is because unique checks on the model are handled in-memory using a full-table scan.
Solution: these cases should be handled in the backend using unique checks and SQL Server Unique Indices.