4

We've got a system where we create long-running batch jobs.

The jobs are created, they then run for x amount of minutes and they are then presented to the user for review.

The RESTful verb and endpoint names are fairly straightforward for creating a job.

  • POST: batch-job, creates a new job.
  • PATCH: batch-job, updates the job with the review of the user.

Some jobs may fail because the server was taken down mid-processing. I'm building now the ability to resume a job, which continues processing the job from it's last succesful point.

How should I name my endpoint while adhering to the REST naming conventions?

Obviously doing something like:

POST: batch-job/restart

is more RPC-like and thus not ideal.

  • 1
    @JamesT The word "restart" was probably misleading. What I meant was "resume", which continues the job processing from the last succesful point. Edited. – Nik Kyriakides Apr 9 '18 at 14:13
  • 2
    REST has no naming conventions for URLs. – Eric Stein Apr 9 '18 at 14:16
  • 1
    @NicholasKyriakides, verbs needs to be avoided, you are right. Per example, a POST /orders is better than POST /orders/create. But there are specific cases where the verbs are the only good way to describe what your restpoint do. – Dherik Apr 9 '18 at 14:23
  • 1
    REST doesn't allow for a "restart" URL. Have one if you like, but have no illusions about its RESTfulness. The closest you might get is exposing a work queue and posting to it. – cHao Apr 9 '18 at 14:23
  • 1
    @NicholasKyriakides You are incorrect. REST says URLs should be considered opaque. There is no mention of URL naming conventions in the dissertation, and none in the HTTP spec. I don't disagree that it's "considered best practice", but it has nothing to do with REST at all. – Eric Stein Apr 9 '18 at 14:47
4

This is an application for state, which is what the S in REST stands for. The batch jobs you're talking about have a state themselves, which makes them easy to model.

Give each one a state which, depending on how complex you want to make it, might have values like these:

  • pending - Submitted but not started.
  • running - Running but not completed.
  • finished - Not running, but ran to completion.
  • abended - Not running, ended abnormally and requires restart to complete.

A client wanting an ABENDed job to be restarted can PATCH the resource (or PUT it if it's independent, e.g., /batch-job/12345/state) and set the state to running. The system's reaction would be to see the transition from abend to running and restart it from the beginning.

The code behind your model will need to check that the user doesn't do anything invalid such as forcing a finished job back to pending.

The system itself will need to make sure running jobs have their states set properly to abend when something goes wrong. I'd recommend setting them during both orderly shutdowns and at startup in case the system loses power without warning.

0

REST doesn't have naming conventions, per se. The idea is that individual URLs opaquely refer to specific resources, the state of which can be retrieved or updated by clients. That said, a common pattern for job resources is

  • POST /job -> creates/returns a /job/$job resource, e.g. in the Location: header
  • GET /job/$jobid -> get details about the job instance
  • PATCH /job/$jobid -> modify the job resource

The job state is usually a field in the resource. To restart a job, PATCH a modification to the resource data structure.

Good design of job resources can be subtle, because jobs typically have a state machine of acceptable sub-states, and a limited number of ways that the state graph can be traversed. To provide maximum flexibility, one usually wants to make that state machine explicit in the resource- e.g. with a pair of fields- sub-state and status- or even an array of sub-state and status. Making the machine explicit allows users to specify whatever state changes they want. Invalid state changes can be responded to with 4xx errors.

0

How should I name my endpoint while adhering to the REST naming conventions?

REST doesn't care what spelling you use for your resource identifiers.

Think about how you would work through exercise in your web browser. You would fill out a form and submit the job; you'd get back some sort of receipt, which would include a link to status page. You could load/refresh the status page to see how things are going. If the server were taken down mid processing, that the job would fail, and the status page would be updated to reflect that. You might, for instance, find a form on that page that, when you submit it, resumes the job.

At no point in this flow do you, the client, need to figure out how to spell an identifier. You just follow links and fill in forms.

That's REST.

/a216fc62-6e0b-44da-8744-c7a8b4aae043 is a perfectly reasonable identifier for a resource that is going to handle a message.

For that matter, so is: /batch-job/restart

If you want the URI to be hackable, that's also fine -- but it's not a REST constraint. There are good reasons that you might want to make the URI hard to hack.

It's absolutely fine to POST a message to an endpoint, and have the endpoint figure out what to do based on the contents of the message body. So you can have a single endpoint that handles multiple kinds of message. This can be really convenient because the POST message will invalidate the representation of the resource cached by any participant that can read the request and response.

For example, since you know the "status page resource" will be changed by the instruction to resume the job, it may make sense to sent the resume message to that resource.

-1

If you are disturbed by the restfullness of any POST method, you can simply add the word 'request' to the end. eg.

POST: batch-job/restart = BAD!

when you add the magic restful word!

POST: batch-job/restartRequest = GOOD!

This works with almost anything, because you can always POST a request!

*as long as you include a stamp

  • I sometimes fail to see beyond your reputation and blindly accept your answers. I'm not impressed this time but I guess it's an alternative I might consider :) – Nik Kyriakides Apr 9 '18 at 14:56
  • I think this option might seem more palatable if you also had a requirement to keep track of a restart requests. Then it would probably feel more correct to expose the request as a resource. But, requirement or not, this still works as a way to keep your API RESTful. – MetaFight Apr 9 '18 at 15:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.