I am creating a RESTful web service and some of the resources are computing or processing functions. For instance, it is possible for a user to scale and convert images through the API by submitting an image and receiving the scaled or converted image back.
According to the RESTful Web Services Cookbook, section 2.5, I should use GET:
Treat the processing function as a resource, and use HTTP GET to fetch a
representation containing the output of the processing function. Use query
parameters to supply inputs to the processing function.
This is clear for cases where the inputs are simple (such as the long/lat coordinates of a point). However, should I follow the same advice for larger inputs such as images? As far as I know it is not possible to send this much data as a query parameter.
Use POST. In effect you are doing an Image Upload and processing on the server. Can't think of another way to do it unless the image is already stored on the server.
The image is a resource. Use PUT to put the resource on the server, then GET the resource, supplying parameters indicating your desired size.
Due to protocol limitations on HTTP I advice against it. This is a very valid very viable example of an exception that should be made to this rule.
Check out this link http://support.microsoft.com/default.aspx?scid=KB;en-us;q208427. It says that the maximum URL for IE is 2083 characters
Related
A few time ago I participate from a interview where had a question about REST modelling, and how the best way to implement it. The question was:
You have an REST API where you expose a method to consult the distance between two point, although you must save each request to this method to expose the request history.
And I was questioned about which HTTP method should be used on this case, for me the logic answer in that moment was the GET method (to execute the both actions). After this the interviewer asked me why, because since we are also storing the request, this endpoint is not idempotent anymore, after that I wasn't able to reply it. Since this stills on my mind, so I decided to verify here and see others opinions about which method should be used for this case (or how many, GET and POST for example).
You have an REST API where you expose a method to consult the distance between two point, although you must save each request to this method to expose the request history.
How would you do this on the web? You'd probably have a web page with a form, and that form would have input controls to collect the start and end point. When you submit the form, the browser would use the data in the controls, as well as the form metadata and standard HTML processing rules to create a request that would be sent to the server.
Technically, you could use POST as the method of the form. It's completely legal to do that. BUT, as the semantics of the request are "effectively read only", a better choice would be to use GET.
More precisely, this would mean having a family of similar resources, the representation of which includes information about the two points described in the query string.
That family of similar resources would probably be implemented on your origin server as a single operation/route, with a parser extracting the two points from the query string and passing them along to the function as arguments.
the interviewer asked me why, because since we are also storing the request, this endpoint is not idempotent anymore
This is probably the wrong objection - the semantics of GET requests are safe (effectively read only). So the interview might argue that saving the request history is not read only. However, this objection is invalid, because the semantic constraints apply to the request message, not the implementation.
For instance, you may have noticed that HTTP servers commonly add an entry to their access log for each request. Clearly that's not "read only" - but it is merely an implementation detail; the client's request did not say "and also log this".
GET is still fine here, even though the server is writing things down.
One possible objection would be that, if we use GET, then sometimes a cache will return an previous response rather than passing the request all the way through to the origin server to get logged. Which is GREAT - caches are a big part of the reason that the web can be web scale.
But if you don't want caching, the correct way to handle that is to add metadata to the response to inhibit caching, not to change the HTTP method.
Another possibility, which is more consistent with the interviewer's "idempotent" remark, is that they wanted this "request history" to be a resource that the client could edit, and that looking up distances would be a side effect of that editing process.
For instance, we might have some sort of an "itinerary" resource with one or more legs provided by the client. Each time the client modifies the itinerary (for example, by adding another leg), the distance lookup method is called automatically.
In this kind of a problem, where the client is (logically) editing a resource, the requests are no longer "effectively read only". So GET is off the table as an option, and we have to look into the other possibilities.
The TL;DR version is that POST would always be acceptable (and this is how we would do it on the web), but you might prefer an API style where the client edits the representation of the resource locally, in which case you would let the client choose between PUT and PATCH.
I use Potoswipe in my project. Potoswipe requires the definition of the images size. In a time when I used PHP that was a simple, nowadays in the serverless time it looks like an issue.
How can I get an image size on a client? I’ve checked few cloud storages providers they all are offering resizing but it is not exactly what I’m looking for, I need a full image property before upload image when I initialize the App.
The easiest thing is to find a hosting service with an API that provides the metadata you need.
Failing that, you can work out the dimensions of an image by looking at just the first few dozen bytes. All modern image formats contain dimensions in a file header. Examples in three languages are linked to in the [Photoswipe FAQ][1].
So, you need to download enough bytes (this varies per file format). To do this you need to use the Range header in the HTTP request. For example:
curl http://i.imgur.com/z4d4kWk.jpg -i -H "Range: bytes=0-1023"
... will get the first kilobyte of that image. Whatever HTTP client you use, it will have a way to set a request header.
I am building my first REST API. I could do most of my queries without any problem but now I encountered a use case I don't know how to solve.
Here is the use case.
I submit a dataset to the API, the dataset is then stored in database (this part works as intended). When stored in the database, it creates different resources due to business rules.
So now I don't know how to inform the user what is the location of the newly created resource since I could have more than one.
I read this Can the Location header be used for multiple resource locations in a 201 Created response? which tells me that only one location header is allowed.
Should I rethink my POST method? Should I use a different way to acknowledge the user where are the resources?
Yes, the Location header requires a single identifier. It's intended for one resource you should follow in order to complete the request according to some predefined semantics.
You can use the Link header instead. Then you can have multiple URIs. Check the RFC 5988 here for a few examples and don't forget to document it properly.
As an alternative, keep in mind that the semantics of the POST method are determined by you, so there's nothing wrong with returning the list of links in the response payload, as long as the resource format allows it in some way and it's documented.
I have a large byte file (log file) that I want to upload to server using PUT request. The reason I choose PUT is simply because I can use it to create a new resource or update an existing resource.
My problem is how to handle situation when server or Network disruption happens during PUT request.
That is say I have a huge file, during the transfer of which, Network failure happens. When the network resumes, I dont want to start the entire upload. How would I handle this?
I am using JAX-RS API with RESTeasy implementation.
Some people are using the Content-Range Header to achieve this but many people (like Mark Nottingham) state that this is not legal for requests. Please read the comments to this answer.
Besides there is no support from JAX-RS for this scenario.
If you really have the repeating problem of broken PUT requests I would simply let the client slice the files:
PUT /logs/{id}/1
PUT /logs/{id}/2
PUT /logs/{id}/3
GET /logs/{id} would then return the aggregation of all successful submitted slices.
In my iPhone I need to show a number of images from remote URL. Some of the URL may download some amount of data and but it may not contain actual image data. So what I need to do to check whether the downloaded data is an image data or not?
Thnx in advance,
Syam S
Do you mean that you're given the actual URLs of the images (e.g. http://sstatic.net/so/img/logo.png), and need to determine whether they're valid images, or do you mean that you're given the URL of a page which may or may not contain images?
Assuming the former (which seems more likely, and is easier than the other case), you'll want to look at the Content-type header returned by the server when you request the URL. Its value will generally be something self-explanatory, like text/html, image/png, image/gif, and so on. If you want image data, it should suffice to check whether the string starts with image/ — although you might want to refine that method if it turns out not to be accurate enough for your needs.
To get this header in an iPhone app, you'll probably want to use the methods described in Apple's Communicating with HTTP Servers guide on their iPhone developer site. If you're only interested in the headers, you might consider using CFReadStreamCreateForStreamedHTTPRequest (instead of what the guide suggests, which is CFReadStreamCreateForHTTPRequest) to read the response. This will avoid buffering all the response data, and will let you download what you need.