I'm creating a Web API with a lot of REST Resources. My service also have some tasks which should be started on demand. for instance "Start sending emails".
For now I do have a specific URL which I call "api/v1/start"
in order to start emails queue sending. But I'm afraid that it is not in comply with the REST standard.
How can I add this feature on my RESTfull service. And... Is REST a good option for this demand or should I ignore it?
3 Answers 3
For now I do have a specific URL which I call "api/v1/start" in order to start emails queue sending. But I'm afraid that it is not in comply with the REST standard.
REST doesn't care what spelling you use for your resource identifiers. /api/v1/start
is fine.
(Technically, Roy Fielding has had very unkind things to say about the v1
part. That's a different issue than the one you are currently asking about, though)
How can I add this feature on my RESTfull service. And... Is REST a good option for this demand or should I ignore it?
There are two common patterns.
One is to POST a message to some endpoint, that understands how to interpret the message and do the right thing. This is analogous to what we do when we submit a web form in a browser. The consumer needs to know which links to follow, and to identify the fields it needs to change, and then the message goes wherever.
The other pattern is a more declarative approach, where you PUT a representation of the way you want the resource to be, and the origin server interprets the new representation and figures out how to bring that about.
Example: imagine trying to write a REST api for a kitchen oven. The oven is off, and our goal is to turn it on with a target setting of 450F.
In the first approach, we would GET
the current representation of the oven, and it would have a form on in, with semantic cues explaining the different fields. We would enter 450F into the form, and submit it. That would be converted into a POST request, and sent to the server for processing.
In the second approach, we would GET
the current representation of the oven, with semantic cues telling us the current temperature. Using our favorite editor, we would modify our local copy of the representation with the desired temperature of 450F, and then PUT
the new representation back to the server, which would then figure out how to achieve our desired target state.
What does Roy Fielding Says?
See, for example, this tweet from 2013
a "v1" is a middle finger to your API customers, indicating RPC/HTTP (not REST)
-
What does Roy Fielding Says?Daniel Santos– Daniel Santos2018年07月10日 17:57:55 +00:00Commented Jul 10, 2018 at 17:57
Seems to me that you are talking about on how start a job manually:
My service also have some tasks which should be started on demand. for instance "Start sending emails".
Well, send e-mails using this endpoint api/v1/start
is very vague in my opinion. What you are really starting? Seems to me that you are starting the "version" (v1), what does not make any sense. The URL needs to be auto-explaining about the resource. Sometimes this is possible, sometimes it's not.
In your case, maybe you could separate the resources used by the application from the jobs
requests. So, you can end up with:
POST /api-job/v1/emails/queues/
I choose POST because is not a PUT, DELETE, GET or PATCH. Sometimes you don't have a good Http method to choose, so the POST
acts like the right choice.
I choose to separate the /api/
from /api-jobs/
. Try to no mix the resources used by the final user application with the resources used by some kind of backend or scheduler. This help you to control each API independently. You can replace jobs
with tasks
if you prefer.
The emails/queues/
is arguable. I make a decision to choose this kind of address, but queues/emails
or only emails
are also options. The choice depends if you are thinking in have other start of queues and/or start another tasks for emails, like:
POST /api-job/v1/emails/queues/ # start the email sending
DELETE /api-job/v1/emails/queues/ # delete all emails on queue
DELETE /api-job/v1/emails/{email-type} # delete all emails from specific type (that are not on the queue yet)
These are only examples.
-
POST
should create a new resource and return the URI to the caller. The DELETE calls (orPUT
,GET
, ...) would be against the resource created byPOST
.GET
on the queues could provide a list of the existing resources.JimmyJames– JimmyJames2018年06月18日 18:08:20 +00:00Commented Jun 18, 2018 at 18:08
The other answers are on the right track but I think a little more specifics might help here. Based on what you have described, I would probably go with something like this:
Root Resource:
api/v1/emails
# this can really be anything. Choose something that is intuitive and distinct.
POST
create a new email subscription. Possible parameters are: address, filters. Returns a URI api/v1/emails/<subscription-id>
GET
returns the list of the current subscription URIs.
Subscription Resource
api/v1/emails/<subscription-id>
GET
retrieve subscription details
PUT
change settings for subscription
DELETE
remove/cancel subscription
PUT
,POST
,GET
. This is crucial when discussing REST.