REST API update and email address in one record where the ID has multiple records - rest

What's the equivalent REST method and request for this sql query?
UPDATE user
SET email = 'newemail#etc.com'
WHERE email = 'oldemail#etc.com'
AND account_number = 1234
Would it be
PATCH api/users/1234/oldemail#etc.com
{
email:"newemail#etc.com"
}
or should I create a new method, something like this?
PATCH api/update-email/1234
{
oldEmail:"oldemail#etc.com",
newEmail:"newemail#etc.com"
}
Note: the account_number is not the primary key id

You are updating an existing record, you should use PATCH instead of POST.
Refs:
RESTful API Design — PUT vs PATCH
REST – PUT vs POST
RESTful API Design: 13 Best Practices to Make Your Users Happy

What's the equivalent REST method and request for this sql query?
How would you do it on a web page? You'd POST form data.
For instance, if you were to
GET /emailAddresses
and then you happened to notice that there was a mistake in the list that you wanted to fix, you would probably click on the "fix this email" link, which would load a new form
GET /fixThisEmail?oldEmail=oldemail#example.com
And then you would fill in the replacement address into the form (which would have the original address preloaded into an input control). Since the /emailAddresses resource is the cachable data that you want to change, the form submission would probably look like
POST /emailAddresses
Content-Type: application/x-www-form-urlencoded
oldEmail=oldemail#example.com&newEmail=newemail#example.com
If instead you wanted to use a remote authoring idiom, you might reasonably edit your own local copy of the email addresses list to correct the error, and then send the revised representation back to the server
GET /emailAddresses
(make the edit in your local copy)
PUT /emailAddresses
PATCH is convenient when the list is much bigger than the http headers and the edit is small relative to the size of the list.
GET /emailAddresses
(make the edit in your local copy)
PATCH /emailAddresses
... but, notice that for both PUT and PATCH, you are going to need to figure out how to extract from the request-body the things that have changed, and compute the right SQL update query to use. Getting the "old" email address to match on may be painful if it isn't present in the new representation.
You can make that somewhat simpler by using a bespoke patch document representation, but that restricts the range of general purpose clients that can use your API.

Related

REST: How to support create-Or-Update and partial-update ? (aka PUT vs PATCH)

We are designing WebAPI for our software for managing ecommerce product information. We want to provide (among many others) two operations:
Simple one: allow user to add/modify existing product information:
don't create new product if it not exists
don't delete any information from existing product which was not provided in this request
In my opinion HTTP PATCH method is proper way to handle this scenario (with json-patch or json-merge-ptach) with URL like this: /products/{ID}
Harder one: allow user to add/modify existing product or create one
create product if not exists in DB
don't delete any information from existing product which was not provided in this request (same behaviour as in first case)
I'm struggling with designing REST endpoint for this second use case. I have few options but none of them fits perfectly for me in the REST principles:
a) Add custom HTTP header to the endpoint designed for first case (patch) to allow a caller to control of "not found behaviour" eg. create-entity-when-not-exists: true/false - but in my opinion PATCH shouldn't be used for creating resources.
b) Design new endpoint using PUT with special header "preserve-not-provided-data" - this on the other hand violates for me PUT principles because PUT is create-or-replace not create-or-update method
c) Create PATCH for /products URL (without {ID} at the end) - in this case we are updating whole collection(resource) of products - so if product exists we can update it or create new one if not exists.
For now c) solution looks fine for me with one exception: If in the future we would like to support batch operations (for both use cases: 1 and 2) we would like to use /products URL and it will conflict with URL from solution c)
What do you think ? Do you have any other ideas ?
PUT and PATCH have differing message semantics, but the core context ("remote authoring") is the same. In both cases, the client request is "Please, server, make your representation of this resource match my local copy".
For example, I GET a JSON document from the server. I make local edits to it. Now I want to "save" my changes on the server. If the document is modest in size, I might just send the entire revised document over the network. If the document is very large, and my changes are modest, then I might instead send the patch instead.
If you imagine using HTTP to publish edits of HTML web pages to a server, then you've got the right frame of reference. There's not a lot of practical difference between "please patch the title of your copy of the document" and "here is a complete new copy of the document, with my edit to the title". The bytes on disk are going to be the same in either case.
Given that, it would be very odd if those two methods for publishing a new revision of the document were to have vastly different side effects.
Your third approach, based on modifying /products, is potentially fine for both your individual and batch. The server gets the new representation of /products (or the patch document describing the changes), decides whether to accept the changes, and if so computes what it needs to do to its own database to make things work.
Note:
A PUT request applied to the target resource can have side effects on other resources.
The HTTP specification is relatively strict about what the message means, but offers the server a lot of leeway in how it behaves in response.

Flask:Confused over using PUT/POST in Rest API

Respected Elders/Programmers/Learned-people,
I have read a very popular answer here about using PUT or POST, but I couldn't decipher from it as to what is the correct way to do so. Almost every answer has comments saying this is wrong/this is right. Mighty confused here.
My requirements:
Sending 2 Json files to the server, one to be inserted in Database and other to be updated. I thought I would use PUT to update, and POST to Insert into the database. That way, on the client side itself I would decide whether to insert or update.
Confusion: Since, the client alone is responsible for its data to be created/updated on the server, even POST in my case upon being repeated would insert the same thing (insert into table values) over and over, behaving as idempotent OR would give an error (Because of primary key conflict). Finally, it would not create something new upon firing it twice.
Question: Is it correct to use PUT for updation, and POST for insertion?
PUT can also be used for creating. What's important is the url. This is generally the accepted pattern:
PUT /collection/1234 <- Update a specific item OR create it
POST /collection <- Add a new item to a collection
Which one is right for you depends on a few things. Does the server determine the url of the new item, or does the client?
If the client can figure out what the url of a new item becomes, using PUT might be better because you can more easily turn it into an idempotent request.
Remember that with a PUT request the intent is always that you are replacing the resource at the target url with a new state.
However, if the server creates the url pattern (maybe you have an auto-incrementing id), POST is better. POST doesn't have to be on the parent collection but it's common.
If you want POST and want idempotence, you need some other way to figure out something was a repeated request. You get that for free with PUT. For example, the Stripe API solves this by adding a non-standard Idempotency-Key header.

What happens if i try to post one POST request with existing record in the database

As per my knowledge the main difference between PUT and POST method in REST is that POST request will create a new record where as PUT request will update the existing record/ create new record if not present.
Now my question is that :
Suppose we have a User with Id = 1 and name= "Pritam" in database.
Now if i try to make a POST request with request body Id = 1 and name= "Pritam", then what happens. (Duplicate records). will a new record will get created or what happens exactly.
Please help me to understand the difference between PUT and POST method. When to use PUT and When to use POST in real time scenarios.
As per my knowledge the main difference between PUT and POST method in REST is that POST request will create a new record where as PUT request will update the existing record/ create new record if not present.
That's not right. (It's also not your fault -- that misunderstanding is common). The real differences in the semantics of POST and PUT are currently described by RFC 7231
POST is the more general method, which can be used for any operation on the target resource
PUT is more specific - it indicates that the included document is intended as a replacement for the representation on the server.
Suppose we have a User with Id = 1 and name= "Pritam" in database. Now if i try to make a POST request with request body Id = 1 and name= "Pritam", then what happens. (Duplicate records). will a new record will get created or what happens exactly.
Those are implementation details; precisely the sort of thing that the REST API is insulating the client from needing to understand (as far as the client is concerned, the server is just a web site).
The "right" thing in your domain might be:
create a new user in your domain model, using the information in the POST message-body, and possibly creating a duplicate, or
report an error to the client, because of the conflict
report success to the client, with reference to the previously created user
None of those things happens by magic, you actually have to choose what makes sense for your circumstances and implement it, then work out the right way to describe what has happened in the body of the HTTP Response, and what information to include in the metadata so that generic components can intelligently participate in the exchange.

How to design RESTful search/filtering? [closed]

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 4 years ago.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
Improve this question
I'm currently designing and implementing a RESTful API in PHP. However, I have been unsuccessful implementing my initial design.
GET /users # list of users
GET /user/1 # get user with id 1
POST /user # create new user
PUT /user/1 # modify user with id 1
DELETE /user/1 # delete user with id 1
So far pretty standard, right?
My problem is with the first one GET /users. I was considering sending parameters in the request body to filter the list. This is because I want to be able to specify complex filters without getting a super long url, like:
GET /users?parameter1=value1&parameter2=value2&parameter3=value3&parameter4=value4
Instead I wanted to have something like:
GET /users
# Request body:
{
"parameter1": "value1",
"parameter2": "value2",
"parameter3": "value3",
"parameter4": "value4"
}
which is much more readable and gives you great possibilities to set complex filters.
Anyway, file_get_contents('php://input') didn't return the request body for GET requests. I also tried http_get_request_body(), but the shared hosting that I'm using doesn't have pecl_http. Not sure it would have helped anyway.
I found this question and realized that GET probably isn't supposed to have a request body. It was a bit inconclusive, but they advised against it.
So now I'm not sure what to do. How do you design a RESTful search/filtering function?
I suppose I could use POST, but that doesn't seem very RESTful.
The best way to implement a RESTful search is to consider the search itself to be a resource. Then you can use the POST verb because you are creating a search. You do not have to literally create something in a database in order to use a POST.
For example:
Accept: application/json
Content-Type: application/json
POST http://example.com/people/searches
{
"terms": {
"ssn": "123456789"
},
"order": { ... },
...
}
You are creating a search from the user's standpoint. The implementation details of this are irrelevant. Some RESTful APIs may not even need persistence. That is an implementation detail.
If you use the request body in a GET request, you're breaking the REST principle, because your GET request won't be able to be cached, because cache system uses only the URL.
What's worse, your URL can't be bookmarked, because the URL doesn't contain all the information needed to redirect the user to this page.
Use URL or Query parameters instead of request body parameters, e.g.:
/myapp?var1=xxxx&var2=xxxx
/myapp;var1=xxxx/resource;var2=xxxx
In fact, the HTTP RFC 7231 says that:
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
For more information take a look here.
It seems that resource filtering/searching can be implemented in a RESTful way. The idea is to introduce a new endpoint called /filters/ or /api/filters/.
Using this endpoint filter can be considered as a resource and hence created via POST method. This way - of course - body can be used to carry all the parameters as well as complex search/filter structures can be created.
After creating such filter there are two possibilities to get the search/filter result.
A new resource with unique ID will be returned along with 201 Created status code. Then using this ID a GET request can be made to /api/users/ like:
GET /api/users/?filterId=1234-abcd
After new filter is created via POST it won't reply with 201 Created but at once with 303 SeeOther along with Location header pointing to /api/users/?filterId=1234-abcd. This redirect will be automatically handled via underlying library.
In both scenarios two requests need to be made to get the filtered results - this may be considered as a drawback, especially for mobile applications. For mobile applications I'd use single POST call to /api/users/filter/.
How to keep created filters?
They can be stored in DB and used later on. They can also be stored in some temporary storage e.g. redis and have some TTL after which they will expire and will be removed.
What are the advantages of this idea?
Filters, filtered results are cacheable and can be even bookmarked.
I think you should go with request parameters but only as long as there isn't an appropriate HTTP header to accomplish what you want to do. The HTTP specification does not explicitly say, that GET can not have a body. However this paper states:
By convention, when GET method is
used, all information required to
identify the resource is encoded in
the URI. There is no convention in
HTTP/1.1 for a safe interaction (e.g.,
retrieval) where the client supplies
data to the server in an HTTP entity
body rather than in the query part of
a URI. This means that for safe
operations, URIs may be long.
As I'm using a laravel/php backend I tend to go with something like this:
/resource?filters[status_id]=1&filters[city]=Sydney&page=2&include=relatedResource
PHP automatically turns [] params into an array, so in this example I'll end up with a $filter variable that holds an array/object of filters, along with a page and any related resources I want eager loaded.
If you use another language, this might still be a good convention and you can create a parser to convert [] to an array.
FYI: I know this is a bit late but for anyone who is interested.
Depends on how RESTful you want to be, you will have to implement your own filtering strategies as the HTTP spec is not very clear on this. I'd like to suggest url-encoding all the filter parameters e.g.
GET api/users?filter=param1%3Dvalue1%26param2%3Dvalue2
I know it's ugly but I think it's the most RESTful way to do it and should be easy to parse on the server side :)
Don't fret too much if your initial API is fully RESTful or not (specially when you are just in the alpha stages). Get the back-end plumbing to work first. You can always do some sort of URL transformation/re-writing to map things out, refining iteratively until you get something stable enough for widespread testing ("beta").
You can define URIs whose parameters are encoded by position and convention on the URIs themselves, prefixed by a path you know you'll always map to something. I don't know PHP, but I would assume that such a facility exists (as it exists in other languages with web frameworks):
.ie. Do a "user" type of search with param[i]=value[i] for i=1..4 on store #1 (with value1,value2,value3,... as a shorthand for URI query parameters):
1) GET /store1/search/user/value1,value2,value3,value4
or
2) GET /store1/search/user,value1,value2,value3,value4
or as follows (though I would not recommend it, more on that later)
3) GET /search/store1,user,value1,value2,value3,value4
With option 1, you map all URIs prefixed with /store1/search/user to the search handler (or whichever the PHP designation) defaulting to do searches for resources under store1 (equivalent to /search?location=store1&type=user.
By convention documented and enforced by the API, parameters values 1 through 4 are separated by commas and presented in that order.
Option 2 adds the search type (in this case user) as positional parameter #1. Either option is just a cosmetic choice.
Option 3 is also possible, but I don't think I would like it. I think the ability of search within certain resources should be presented in the URI itself preceding the search itself (as if indicating clearly in the URI that the search is specific within the resource.)
The advantage of this over passing parameters on the URI is that the search is part of the URI (thus treating a search as a resource, a resource whose contents can - and will - change over time.) The disadvantage is that parameter order is mandatory.
Once you do something like this, you can use GET, and it would be a read-only resource (since you can't POST or PUT to it - it gets updated when it's GET'ed). It would also be a resource that only comes to exist when it is invoked.
One could also add more semantics to it by caching the results for a period of time or with a DELETE causing the cache to be deleted. This, however, might run counter to what people typically use DELETE for (and because people typically control caching with caching headers.)
How you go about it would be a design decision, but this would be the way I'd go about. It is not perfect, and I'm sure there will be cases where doing this is not the best thing to do (specially for very complex search criteria).

RESTful way to create multiple items in one request

I am working on a small client server program to collect orders. I want to do this in a "REST(ful) way".
What I want to do is:
Collect all orderlines (product and quantity) and send the complete order to the server
At the moment I see two options to do this:
Send each orderline to the server: POST qty and product_id
I actually don't want to do this because I want to limit the number of requests to the server so option 2:
Collect all the orderlines and send them to the server at once.
How should I implement option 2? a couple of ideas I have is:
Wrap all orderlines in a JSON object and send this to the server or use an array to post the orderlines.
Is it a good idea or good practice to implement option 2, and if so how should I do it.
What is good practice?
I believe that another correct way to approach this would be to create another resource that represents your collection of resources.
Example, imagine that we have an endpoint like /api/sheep/{id} and we can POST to /api/sheep to create a sheep resource.
Now, if we want to support bulk creation, we should consider a new flock resource at /api/flock (or /api/<your-resource>-collection if you lack a better meaningful name). Remember that resources don't need to map to your database or app models. This is a common misconception.
Resources are a higher level representation, unrelated with your data. Operating on a resource can have significant side effects, like firing an alert to a user, updating other related data, initiating a long lived process, etc. For example, we could map a file system or even the unix ps command as a REST API.
I think it is safe to assume that operating a resource may also mean to create several other entities as a side effect.
Although bulk operations (e.g. batch create) are essential in many systems, they are not formally addressed by the RESTful architecture style.
I found that POSTing a collection as you suggested basically works, but problems arise when you need to report failures in response to such a request. Such problems are worse when multiple failures occur for different causes or when the server doesn't support transactions.
My suggestion to you is that if there is no performance problem, for example when the service provider is on the LAN (not WAN) or the data is relatively small, it's worth it to send 100 POST requests to the server. Keep it simple, start with separate requests and if you have a performance problem try to optimize.
Facebook explains how to do this: https://developers.facebook.com/docs/graph-api/making-multiple-requests
Simple batched requests
The batch API takes in an array of logical HTTP requests represented
as JSON arrays - each request has a method (corresponding to HTTP
method GET/PUT/POST/DELETE etc.), a relative_url (the portion of the
URL after graph.facebook.com), optional headers array (corresponding
to HTTP headers) and an optional body (for POST and PUT requests). The
Batch API returns an array of logical HTTP responses represented as
JSON arrays - each response has a status code, an optional headers
array and an optional body (which is a JSON encoded string).
Your idea seems valid to me. The implementation is a matter of your preference. You can use JSON or just parameters for this ("order_lines[]" array) and do
POST /orders
Since you are going to create more resources at once in a single action (order and its lines) it's vital to validate each and every of them and save them only if all of them pass validation, ie. you should do it in a transaction.
I've actually been wrestling with this lately, and here's what I'm working towards.
If a POST that adds multiple resources succeeds, return a 200 OK (I was considering a 201, but the user ultimately doesn't land on a resource that was created) along with a page that displays all resources that were added, either in read-only or editable fashion. For instance, a user is able to select and POST multiple images to a gallery using a form comprising only a single file input. If the POST request succeeds in its entirety the user is presented with a set of forms for each image resource representation created that allows them to specify more details about each (name, description, etc).
In the event that one or more resources fails to be created, the POST handler aborts all processing and appends each individual error message to an array. Then, a 419 Conflict is returned and the user is routed to a 419 Conflict error page that presents the contents of the error array, as well as a way back to the form that was submitted.
I guess it's better to send separate requests within single connection. Of course, your web-server should support it
You won't want to send the HTTP headers for 100 orderlines. You neither want to generate any more requests than necessary.
Send the whole order in one JSON object to the server, to: server/order or server/order/new.
Return something that points to: server/order/order_id
Also consider using CREATE PUT instead of POST