Pretend I am building a simple image-processing API. This API is completely stateless and only needs three items in the request, an image, the image format and an authentication token.
Upon receipt of the image, the server merely processes the image and returns a set of results.
Ex: I see five faces in this image.
Would this still work with a REST based API? Should this be used with a REST based API?
Most of the examples I have seen when comparing REST and SOAP have been purely CRUD based, so I am slightly confused with how they compare in a scenario such as this.
Any help would be greatly appreciated, and although this question seems quite broad, I have yet to find a good answer explaining this.
REST is not about CRUD. It is about resources. So you should ask yourself:
What are my resources?
One answer could be:
An image processing job is a resource.
Create a new image processing job
To create a new image processing job, mak a HTTP POST to a collection of jobs.
POST /jobs/facefinderjobs
Content-Type: image/jpeg
The body of this POST would be the image.
The server would respond:
201 Created
Location: /jobs/facefinderjobs/03125EDA-5044-11E4-98C5-26218ABEA664
Here 03125EDA-5044-11E4-98C5-26218ABEA664 is the ID of the job assigned by the server.
Retrieve the status of the job
The client now wants to get the status of the job:
GET /jobs/facefinderjobs/03125EDA-5044-11E4-98C5-26218ABEA664
If the job is not finished, the server could respond:
200 OK
Content-Type: application/json
{
"id": "03125EDA-5044-11E4-98C5-26218ABEA664",
"status": "processing"
}
Later, the client asks again:
GET /jobs/facefinderjobs/03125EDA-5044-11E4-98C5-26218ABEA664
Now the job is finished and the response from the server is:
200 OK
Content-Type: application/json
{
"id": "03125EDA-5044-11E4-98C5-26218ABEA664",
"status": "finished",
"faces": 5
}
The client would parse the JSON and check the status field. If it is finished, it can get the number of found faces from the faces field.
Related
I have a request that lasts more than 3 minutes, I want the request to be sent and immediately give the answer 200 and after the end of the work - give the result
The workflow you've described is called asynchronous task execution.
The main idea is to remove time or resource consuming parts of work from the code that handles HTTP requests and deligate it to some kind of worker. The worker might be a diffrent thread or process or even a separate service that runs on a different server.
This makes your application more responsive, as the users gets the HTTP response much quicker. Also, with this approach you can display such UI-friendly things as progress bars and status marks for the task, create retrial policies if task failes etc.
Example workflow:
user makes HTTP request initiating the task
the server creates the task, adds it to the queue and returns the HTTP response with task_id immediately
the front-end code starts ajax polling to get the results of the task passing task_id
the server handles polling HTTP requests and gets status information for this task_id. It returns the info (whether results or "still waiting") with the HTTP response
the front-end displays spinner if server returns "still waiting" or the results if they are ready
The most popular way to do this in Django is using the celery disctributed task queue.
Suppose a request comes, you will have to verify it. Then send response and use a mechanism to complete the request in the background. You will have to be clear that the request can be completed. You can use pipelining, where you put every task into pipeline, Django-Celery is an option but don't use it unless required. Find easy way to resolve the issue
I have been trying to get the response from API gateway, but after countless tries and going through several online answers, I still wasn't able to solve my issue.
When I test my POST method for the API, it gives me proper response on lambda test and API gateway method test, but when I try it from my react app, it doesn't return the same output.
My lambda snippet:
const response = {
statusCode: 200,
body: JSON.stringify({payload: {"key": "value"}})
};
return response;
But the response I am getting using fetch API on my react app:
I am new to AWS and would appreciate if someone point me in the right direction.
So the fetch API allows you to receive responses as a readablestream, which is what it shows you are receiving in that image there. This resource here, should be helpful in how to properly handle the response.
There are also many other commonly used libraries like axios that are primarily promise / callback driven and you won't have to worry about streams too much unless you want to. You should be able to get fetch working with promises too, but I've never done it myself.
In general, streams are really useful when you have a large amount of data and receiving it all at once in a giant chunk would be really slow, cause timeouts, etc.
I've been working on a Dialogflow chatbot that calls a webhook which can often take more than the 5s delay to process and answer the user's request. So, following this post, my webhook sends a response containing a followup event if the processing is too long, and will be able to answer the following request sent by the intent triggered by the event.
Now, while this approach is working great, I have two questions :
Is there any way to send a message ("Please wait, I'm processing your request") to the user on every followup event ?
Since I'm using the Dialogflow-Messenger integration, is there any way to display the three dots "typing" animation while the webhook is processing the request ?
Thanks !
When developing a chatbot, you should keep in mind that you are trying to duplicate how 2 humans interact. You are developing a conversation and in the conversation, we should not keep other person waiting. All your requests should be completed within 4-5 seconds (to avoid timeout by the platform) to have a better UX.
So there is no way to show either Please Wait or animated 3 dots!
Write a good backend code to fetch response faster or tweak and cache your response. Dialogflow is currently designed for 1-1 conversation and cannot provide multiple delayed responses. If you need it that way, you will require to develop your own NLP engine.
I working on a service which scrapes specific links from blogs. The service makes calls to different sites which pulls in and stores the data.
I'm having troubles specifying the url for updating the data on the server where I now use the verb update to pull in the latest links.
I currently use the following endpoints:
GET /user/{ID}/links - gets all previously scraped links (few milliseconds)
GET /user/{ID}/links/update - starts scraping and returned the scraped data (few seconds)
What would be a good option for the second url? some examples I came up with myself.
GET /user/{ID}/links?collection=(all|cached|latest)
GET /user/{ID}/links?update=1
GET /user/{ID}/links/latest
GET /user/{ID}/links/new
Using GET to start a process isn't very RESTful. You aren't really GETting information, you're asking the server to process information. You probably want to POST against /user/{ID]/links (a quick Google for PUT vs POST will give you endless reading if you're curious about the finer points there). You'd then have two options:
POST with background process: If using a background process (or queue) you can return a 202 Accepted, indicating that the service has accepted the request and is about to do something. 202 generally indicates that the client shouldn't wait around, which makes sense when performing time dependent actions like scraping. The client can then issue GET requests on the first link to retrieve updates.
Creative use of Last-Modified headers can tell the client when new updates are available. If you want to be super fancy, you can implement HEAD /user/{ID}/links that will return a Last-Modified header without a response body (saving both bandwidth and processing).
POST with direct processing: If you're doing the processing during the request (not a great plan in the grand scheme of things), you can return a 200 OK with a response body containing the updated links.
Subsequent GETs would perform as normal.
More info here
And here
And here
We are developing a web API which processes potentially very large amounts of user-submitted content, which means that calls to our endpoints might not return immediate results. We are therefore looking at implementing an asynchronous/non-blocking API. Currently our plan is to have the user submit their content via:
POST /v1/foo
The JSON response body contains a unique request ID (a UUID), which the user then submits as a parameter in subsequent polling GETs on the same endpoint:
GET /v1/foo?request_id=<some-uuid>
If the job is finished the result is returned as JSON, otherwise a status update is returned (again JSON).
(Unless they fail both the above calls simply return a "200 OK" response.)
Is this a reasonable way of implementing an asynchronous API? If not what is the 'right' (and RESTful) way of doing this? The model described here recommends creating a temporary status update resource and then a final result resource, but that seems unnecessarily complicated to me.
Actucally the way described in the blog post you mentioned is the 'right' RESTful way of processing aysnchronous operations. I've implemented an API that handles large file uploads and conversion and does it this way. In my opinion this is not over complicated and definitely better then delaying the response to the client or something.
Some additional note: If a task has failed, I would also return 200 OK together with a representation of the task resource and the information that the resource creation has failed.