Dial 202–200–303 for RESTful Asynchronous Process
Tags: restful, api, webservices, architecture
Published: 2020-03-03 19:24:37


Initiating a long-running batch process from RESTful service might sound odd but this is an actual and very valid use case.

```When you are not sure about the use case always start with file or image uploads. — William Shakespeare```
###Use Case:
Converting MP4 to MP3 by uploading a file capped at 25 MB on our imaginary website www.mp4tomp3bywilliams.com
###REST way:
Just to bring you under this use case, say that you are required to implement this functionality using a RESTful service. Just because you have to be lockstep with your organization where everything is achieved using a Web Service, we will be implementing this functionality as a service too.
###Seen this somewhere?
You must have definitely seen this in one or more sites you use in your day-to-day. Most of these sites follow this strategy. Let’s get into the recipe.
##Recipe
We will be using the following ingredients,
- Client-UI App
- Server - Our RESTful service — Let's call it Mp4toMp3 service
- HTTP code 202 — ACCEPTED
- HTTP code 303 — SEE OTHER
- HTTP code 200 — OK

####Step 1: Upload the File
The file will be uploaded from the UI and say that we drop this into one of the following S3 buckets, DropBox or Google Drive and get a Webhook that is accessible by our RESTful service.

####Step 2: Call the Mp4toMp3 service
Using the Link uploaded to a cloud drive we will now call our POST web service. In this case, the call to mp4tomp3 doesn't really abide by the RESTful resource rules. Meaning a good RESTful endpoint will be a valid plural noun like employees or customers but those resources which sound like more of a RPC call is called the Controller Resource . So in our case mp4tomp3 is a controller resource.

    POST https://converteranything.com/converter/mp4tomp3
    -> 202 Accepted
    Location: https://converteranything.com/converter/mp4tomp3/48578

So we trigger a POST to the controller resource, which returns a status code 202 Accepted. This just means that the process is submitted. Using the Location header in the response, the direct URL to infer the status of the submitted job is given to the client. This is again your implementation, you build this URL in the backend which is a link to the extension of this controller resource where 48578 could be the number you assigned or the PID from the OS it's your choice.

####Step 3: Return HTTP 200 but for 2 different reasons
You can now call this returned URL that points to the Status of the just submitted job using the following URL and initiate an HTTP GET call. You can now expect 2 different HTTP status codes in return 303 and 200. We will be talking about 303 shortly. Let's talk about 200 for now.

    https://converteranything.com/converter/mp4tomp3/48578

When we call the above URL we are essentially calling to know the status of the job we submitted. So we need to return a resource to the client when this URL is called and we call this as a process resource. Below is an ideal representation of the process resource when everything is going well.

    HTTP 200
    {
    "percentage_completed":"18%",
    "estimated_time_to_complete":"75 seconds",
    "poll_every":"5 seconds",
    "error":""
    }

The above message from the GET call can be painted by the UI as follows,

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dbvmq3hhlibz5kpj5b9h.png)

And when something is fishy the process resource can look like this,

    HTTP 200
    {
    "percentage_completed":"",
    "estimated_time_to_complete":"",
    "poll_every":"",
    "error":"Unable to access the file"
    }

So when we invoke the GET on the provided process resource URL we return 200 for both to sense progress as well as failure.
####Step 4: The Stupendous Steps of all — 303
HTTP 303 is Redirect to New URI . RESTful is all about exploiting all available HTTP methods instead of you implementing it by yourself. So when we call the process status URL and get a 303 it just means that our async process is completed or at least that’s what you need to implement on the server-side. This redirect can just bring you back to a Conversion Successful message on the UI with a button to download the content or you can get more creative here. But you need to end your async call with a grand 303 to give it a sense of completion.
###Conclusion:
That how you deal with long-running RESTful service calls.
###References:
https://www.amazon.com/RESTful-API-Design-API-University-3/dp/1514735164
https://www.amazon.com/RESTful-Web-APIs-Services-Changing/dp/1449358063