Is it restful to have verbs on the HTTP path instead of the HTTP method?
Yes. REST doesn't care what spelling you use for your identifiers.
I've only been told again and again that this is not restful because it must only use GET, POST, PUT, DELETE and PATCH to remain restful.
One of the REST architecture constraints is the uniform interface; describing it in his thesis, Fielding wrote
By applying the software engineering principle of generality to the component interface, the overall system architecture is simplified and the visibility of interactions is improved. Implementations are decoupled from the services they provide, which encourages independent evolvability....
There's nothing particularly magic about [GET, POST, PUT, DELETE, PATCH]. A very long time ago, that list would probably be [GET, HEAD, POST], because those were the only methods that had been standardized in RFC 1945. The others were documented with this warning:
This appendix documents protocol elements used by some existing HTTP implementations, but not consistently and correctly across most HTTP/1.0 applications. Implementors should be aware of these features, but cannot rely upon their presence in, or interoperability with, other HTTP/1.0 applications.
The interoperability is key, in that it means that clients and servers and intermediary components that share an understanding of the message semantics can all cooperate together to produce a result -- without needing to understand the payload of the message.
Today, we have a method registry, with many different methods that you might want to use, including (as it happens) LOCK and UNLOCK. So, assuming your semantics agrees with those documented in the registry, you could use them.
In circumstances where you control both the client and the server, limiting yourself to the registered methods is less critical than it would be otherwise.
If you are targeting clients that understand code on demand, then you can give a generic client a link to download your client code to interact with your services.
Best Answer
In your latter scheme, you keep verbs in the URLs of your resources. This should be avoided as the HTTP verbs should be used for that purpose. Embrace the underlying protocol instead of ignoring, duplicating or overriding it.
Just look at
DELETE /item/delete/:id
, you place the same information twice in the same request. This is superfluous and should be avoided. Personally, I'd be confused with this. Does the API actually supportDELETE
requests? What if I placedelete
in the URL and use a different HTTP verb instead? Will it match anything? If so, which one will be chosen? As a client of a properly designed API, I shouldn't have to ask such questions.Maybe you need it to somehow support clients that cannot issue
DELETE
orPUT
requests. If that's the case, I'd pass this information in an HTTP header. Some APIs use anX-HTTP-Method-Override
header for this specific purpose (which I think is quite ugly anyway). I certainly wouldn't place the verbs in the paths though.Go for
What's important about the verbs is that they are already well-defined in the HTTP specification and staying in line with these rules allows you to use caches, proxies and possibly other tools external to your application that understand the semantics of HTTP but not your application semantics. Please note that the reason you should avoid having them in your URLs is not about RESTful APIs requiring readable URLs. It's about avoiding unnecessary ambiguity.
What's more, a RESTful API can map these verbs (or any subset thereof) to any set of application semantics, as long as it doesn't go against the HTTP specification. For example, it is perfectly possible to build a RESTful API that only uses GET requests if all operations that it allows are both safe and idempotent. The above mapping is just an example that fits your use case and is compliant with the spec. It doesn't necessarily have to be like this.
Please also mind that a truly RESTful API should never require a programmer to read extensive documentation of available URLs as long as you conform to the HATEOAS (Hypertext as the Engine of Application State) principle, which is one of the core assumptions of REST. The links can be utterly incomprehensible to humans as long as the client application can understand and use them to figure out possible application state transitions.