How to do versioning in the REST API URI address? - rest

I'm looking at ways to version the URIs of a Spring REST API because, in the case of launching a new application, the REST API handles the new application and supports the old application requests for a certain period. But I am in doubt as to what database, system entities, and URIs are in general whenever a version is added to a URI.
Example:
No version, a request to fetch all users:
http://host:8080/api/users
With versioning:
http://host:8080/v1/users
http://host:8080/v2/users
http://host:8080/v1/products
I was thinking of making a User entity and when defining the attributes I note them as not mandatory and the entity is always the most current version. For the 'v2' version of the URI I create a UserV2DTO so that it primarily serves the User entity doing the validations with the required annotations. For the 'v1' version of the URI, let's say that the user does not have the 'dateBirth' attribute and in this way it receives a UserV1DTO that does not have the dateBirth attribute and at the time of converting the DTO to Entity the Entity.dateBirth attribute is null because is required.
What I want to know is if this is a correct form of versioning, because in the database the attributes are not mandatory and the validation of the mandatory is in the DTO? Also I want to know if all the URIs of all the resources need to be changed to the last version or if in the case of 'products' it can stay in V1 until one day it is necessary to change only it?

How to do versioning in the REST API URI address?
Real answer? Any way you want, consistent with your local conventions.
In REST, URI are just identifiers; effectively they are keys used to look up information in a cache. Embedding information in the URI is done at the discretion of the server, and for its own exclusive use.
Roy Fielding, who defined REST while leading the specification work for HTTP/1.1, wrote
The reason to make a real REST API is to get evolvability … a "v1" is a middle finger to your API customers, indicating RPC/HTTP (not REST)
As an example, consider Google -- how many different implementations of web search do you suppose that they have had, over the years? But the API itself has been stable: navigate to the bookmarked home page, enter data in the search form, submit -- dispatching the data to whatever URI was described in the form meta data.
Of course, even if you aren't doing REST, you might still want a URI design that is sane. Using path segments to partition your resource hierarchy has advantages when it comes to relative URI, because you can then use dot-segments to produce other identifiers in the hierarchy.
/v1/users + ../products -> /v1/products
Your life down the road will likely be considerably easier if you are clear as to whether you really have a new resource in each version, or a shared resource with different representations. If someone changes /v2/users, should that also change /v1/users? What are the correct cache invalidation semantics?

Related

REST: book a room example fits architecture?

Is my approach to book a room in a conference hall:
PUT: api/v1/rooms/book/1
GET: api/v1/rooms/1
POST: api/v1/rooms
fits REST architecture?
With your approach, you define the "book" as a resource - which is fine in restful perspective.
But - the http method will be better to be a "POST" for this situation, as you create a new instance of the "book" resource (this is more restfuly in case you consider "book" as a resource, which you are).
and it basically means that the POST method should include the room_id in the request body rather than book/1
Rooms resource:
GET: api/v1/rooms/books/ - All the booking
POST: api/v1/rooms/books - book new (room_id in body) - there's a better restful approach in the next resource:
Book resource
GET: api/v1/rooms/<room_id>/books/ - Get room room_id books
POST: api/v1/rooms/1/book book new (book id in url resource, more restful than rhe rooms resource example)
a book resource
PUT api/v1/rooms/<room_id>/books/<book_id> - Update book information
GET api/v1/rooms/<room_id>/books/<book_id> - Retrieve book information
As you clearly asked for whether your design fits the REST architecture:
Actually the form of the URI is not of relevance in a REST architecture. Clients will use link relation strings to lookup a URI dynamically. I.e. if a client wants to progress to the next page it will look for a URI annotated with next (see registered link relations at IANA). In case there is no fitting link-relation yet present at IANA's registry you can either attempt to register one or fall back to an approach outlined by Web linking extension, which uses a URI that does not necessarily need to target an actual resource but just defines the relation within an own namespace. Technically, each relation builds up a triple (subject, predicate, object), similar to an ontology, where the subject is always the current resource and object always the target resource and the predicate being the link relation name or verb in that triple. A URI can further have multiple link-relations assigned, i.e. create-form https://acme.org/rel/book-room where the first create-form link relation indicates that the resource will provide a form to create a new resource and the second one, the Web linking extension one, will indicate to clients that support this kind of relation that a room can be booked using the underlying URI. This whole indirection allows a server to change its URI scheme anytime it wants to and clients will still be able to make further requests.
Please note though that resources in a REST architecture never have types that are significant to clients. This is similar to the Web we interact on a daily basis. Even though we visit different HTML pages that represent car models, shopping products and what not, the content returned by the server is still a HTML page containing data that could also be expressed in other representation formats. HTML after all just defines which tags are valid within the scope of the HTML document (syntax) received as well what each of these tags expresses (semantics). Through content-type negotiation both client and server can and should agree on a representation format both understand and can operate on.
In case a server expects some client input an approach very similar to traditional Web surfing done by humans can and should be used. Humans usually interact with HTML based Web-Forms. Here, the form teaches a client about the properties a resource supports, the target URI to send the request to, the HTTP operation to use as well as (most often implicitly given) the media type to use for marshalling the payload to before transmitting the request. This way clients learn new features a server has for a resource automatically.
The intent of a REST architecture is besides the decoupling of clients from servers also the freedom of evolution on the server side so that new features can be introduced without breaking any clients. As HTTP and URI define a standard interface that is widely supported by languages and frameworks, the core focus needs to be put on the actual media-type exchanged between client and servers. This is the coupling part between both of them. The overall question here should not be which media-type to support but how many different ones as with each one you support you just increase the likelihood of your application being able to interact with peers in that architecture.
So your actual question whether your URI design fits a REST architecture can't be answered actually as, as mentioned throughout this post, REST is more than meaningful URIs or which HTTP operation you perform on a URI. From a true REST architecture standpoint your URIs are fine as far as they don't violate with the URI specification. In general, one of the best advice to give on designing peers in a REST architecture is to model the whole interaction as if you'd design a browser-based Web interaction and than transfer the same concepts onto a more general application layer using link support through HAL JSON or JSON Hyper-Schema or form-support through HAL forms or ION in case you prefer exchanging JSON payloads.

REST API design for a "reset to defaults" operation

I'm surprised to find so little mention of this dilemma online, and it makes me wonder if I'm totally missing something.
Assume I have a singleton resource called Settings. It is created on init/install of my web server, but certain users can modify it via a REST API, lets say /settings is my URI. I have a GET operation to retrieve the settings (as JSON), and a PATCH operation to set one or more of its values.
Now, I would like to let the user reset this resource (or maybe individual properties of it) to default - the default being "whatever value was used on init", before any PATCH calls were done. I can't seem to find any "best practice" approach for this, but here are the ones I have come up with:
Use a DELETE operation on the resource. It is after all idempotent, and its pretty clear (to me). But since the URI will still exist after DELETE, meaning the resource was neither removed nor moved to an inaccessible location, this contradicts the RESTful definition of DELETE.
Use a POST to a dedicated endpoint such as /settings/reset - I really dislike this one because its the most blatantly non-RESTful, as the verb is in the URI
Use the same PATCH operation, passing some stand-in for "default" such as a null value. The issue I have with this one is the outcome of the operation is different from the input (I set a property to null, then I get it and it has a string value)
Create a separate endpoint to GET the defaults, such as /setings/defaults, and then use the response in a PATCH to set to those values. This doesn't seem to contradict REST in any way, but it does require 2 API calls for seemingly one simple operation.
If one of the above is considered the best practice, or if there is one I haven't listed above, I'd love to hear about it.
Edit:
My specific project has some attributes that simplify this question, but I didn't mention them originally because my aim was for this thread to be used as a reference for anyone in the future trying to solve the same problem. I'd like to make sure this discussion is generic enough to be useful to others, but specific enough to also be useful to me. For that, I will append the following.
In my case, I am designing APIs for an existing product. It has a web interface for the average user, but also a REST (ish) API intended to meet the needs of developers who need to automate certain tasks with said product. In this oversimplified example, I might have the product deployed to a test environment on which i run various automated tests that modify the /settings and would like to run a cleanup script that resets /settings back to normal when I'm done.
The product is not SaaS (yet), and the APIs are not public (as in, anyone on the web can access them freely) - so the audience and thus the potential types of "clients" I may encounter is rather small - developers who use my product, that is deployed in their private data center or AWS EC2 machines, and need to write a script in whatever language to automate some task rather than doing it via UI.
What that means is that some technical considerations like caching are relevant. Human user considerations, like how consistent the API design is across various resources, and how easy it is to learn, are also relevant. But "can some 3rd party crawler identify the next actions it can perform from a given state" isn't so relevant (which is why we don't implement HATEOAS, or the OPTIONS method at all)
Let's discuss your mentioned options first:
1: DELETE does not necessarily need to delete or remove the state contained in the resource targeted by the URI. It just requires that the mapping of target URI to the resource is removed, which means that a consecutive request on the same URI should not return the state of the resource further, if no other operation was performed on that URI in the meantime. As you want to reuse the URI pointing to the client's settings resource, this is probably not the correct approch.
2: REST doesn't care about the spelling of the URI as long as it is valid according to RFC3986. There is no such thing as RESTful or RESTless URI. The URI as a whole is a pointer to a resource and a client should refrain from extracting knowledge of it by parsing and interpreting it. Client and server should though make use of link relation names URIs are attached to. This way URIs can be changed anytime and client will remain to be able to interact with the service further. The presented URI however leaves an RPC kind of smell, which an automated client is totally unaware of.
3: PATCH is actually pretty-similar to patching done by code versioning tools. Here a client should precalculate the steps needed to transform a source document to its desired form and contain these instructions into a so called patch document. If this patch document is applied by someone with the state of a document that matches the version used by the patch document, the changes should be applied correctly. In any other cases the outcome is uncertain. While application/json-patch+json is very similar to the philosophy on a patch-document containing separate instructions, application/merge-patch+json has a slightly different take on it by defining default rules (nulling out a property will lead to a removal, including a property will lead to its adding or update and leaving out properties will ignore these properties in the original document)
4: In this sense first retrieving the latest state from a resource and locally updating it/calculating the changes and then send the outcome to the server is probably the best approach of the ones listed. Here you should make use of conditional requests to guarantee that the changes are only applied on the version you recently downloaded and prevent issues by ruling out any intermediary changes done to that resource.
Basically, in a REST architecture the server offers a bunch of choices to a client that based on his task will chose one of the options and issue a request to the attached URI. Usually, the client is taught everything it needs to know by the server via form representations such as HTML forms, HAL forms or ION.
In such an environment settings is, as you mentioned, a valid resource on its own, so is also a default settings resource. So, in order to allow a client to reset his settings it is just a matter of "copying" the content of the default settings resource to the target settings resource. If you want to be WebDAV compliant, which is just an extension of HTTP, you could use the COPY HTTP operation (also see other registered HTTP operations at IANA). For plain HTTP clients though you might need a different approach so that any arbitrary HTTP clients will be able to reset settings to a desired default one.
How a server wants a client to perform that request can be taught via above mentioned form support. A very simplistic approach on the Web would be to send the client a HTML page with the settings pre-filled into the HTML form, maybe also allow the user to tweak his settings to his wishes beforehand, and then click a submit button to send the request to the URI present in the action attribute of the form, which can be any URI the server wants. As HTML only supports POST and GET in forms, on the Web you are restricted to POST.
One might think that just sending a payload containing the URI of the settings resource to reset and optionally the URI to the default settings to a dedicated endpoint via POST is enough and then let it perform its magic to reset the state to the default one. However, this approach does bypass caches and might let them believe that the old state is still valid. Caching in HTTP works as such that the de-facto URI of a resource is used as key and any non-safe operations performed on that URI will lead to an eviction of that stored content so that any consecutive requests would directly go to the server instead of being served by the cache instead. As you send the unsafe POSTrequest to a dedicated resource (or endpoint in terms of RPC) you miss out on the capability to inform the cache about the modification of the actual settings resource.
As REST is just a generalization of the interaction model used on the human Web, it is no miracle that the same concepts used on the Web also apply onto the application domain level. While you can use HTML here as well, JSON-based formats such as application/hal+json or the above mentioned HAL forms or ION formats are probably more popular. In general, the more media-type your service is able to support, the more likely the server will be to server a multitude of clients.
In contrast to the human Web, where images, buttons and further stuff provide an affordance of the respective control to a user, arbitrary clients, especially automated ones, usually don't coop with such affordances good. As such other ways to hint a client on the purpose of a URI or control element need to be provided, such as link relation names. While <<, <, >, >> may be used on a HTML page link to indicate first, previous, next and last elements in a collection, link relation here provide first, prev, next and last as alternatives. Such link relations should of course be either registered with IANA or at least follow the Web linking extension approach. A client looking up the URI on a prev relation will know the purpose of the URI as well as still be able to interact with the server if the URI ever changes. This is in essence also what HATEOAS is all about, using given controls to navigate the application though the state machine offered by the server.
Some general rules of thumb in designing applications for REST architectures are:
Design the interaction as if you'd interact with a Web page on the human Web, or more formally as a state machine or domain application protocol, as Jim Webber termed it, a client can run through
Let servers teach clients on how requests need to look like via support of different form types
APIs shouldn't use typed resources but instead rely on content type negotiation
The more media type your API or client supports the more likely it will be to interact with other peers
Long story short, in summary, a very basic approach is to offer a client a pre-filled form with all the data that makes up the default settings. The target URI of the action property targets the actual resource and thus also informs caches about the modification. This approach is on top also future-proof that clients will be served automatically with the new structure and properties a resource supports.
... so the audience and thus the potential types of "clients" I may encounter is rather small - developers who use my product, that is deployed in their private data center or AWS EC2 machines, and need to write a script in whatever language to automate some task rather than doing it via UI.
REST in the sense of Fielding's architectural style shines when there are a multitude of different clients interacting with your application and when there needs to be support for future evolution inherently integrated into the design. REST just gives you the flexibility to add new features down the road and well-behaved REST clients will just pick them up and continue. If you are either only interacting with a very limited set of clients, especially ones under your control, of if the likelihood of future changes are very small, REST might be overkill and not justify the additional overhead caused by the careful desing and implementation.
... some technical considerations like caching are relevant. Human user considerations, like how consistent the API design is across various resources, and how easy it is to learn, are also relevant. But "can some 3rd party crawler identify the next actions it can perform from a given state" isn't so relevant ...
The term API design already indicates that a more RPC-like approach is desired where certain operations are exposed user can invoke to perform some tasks. This is all fine as long as you don't call it REST API from Fielding's standpoint. The plain truth here is that there are hardly any applications/systems out there that really follow the REST architectural style but there are tons of "bad examples" who misuse the term REST and therefore indicate a wrong picture of the REST architecture, its purpose as well as its benefits and weaknesses. This is to some part a problem caused by people not reading Fielding's thesis (carefully) and partly due to the overall perference towards pragmatism and using/implementing shortcuts to get the job done ASAP.
In regards to the pragmatic take on "REST" it is hard to give an exact answer as everyone seems to understand different things about it. Most of those APIs rely on external documentation anyway, such as Swagger, OpenAPI and what not and here the URI seems to be the thing to give developers clue about the purpose. So a URI ending with .../settings/reset should be clear to most of the developers. Whether the URI has an RPC-smell to it or whether or not to follow the semantics of the respective HTTP operations, i.e. partial PUT or payloads within GET, is your design choice which you should document.
It is okay to use POST
POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.”
POST /settings HTTP/x.y
Content-Type: text/plain
Please restore the default settings
On the web, you'd be most likely to see this as a result of submitting a form; that form might be embedded within the representation of the /settings resource, or it might live in a separate document (that would depend on considerations like caching). In that setting, the payload of the request might change:
POST /settings HTTP/x.y
Content-Type: application/x-www-form-urlencoded
action=restoreDefaults
On the other hand: if the semantics of this message were worth standardizing (ie: if many resources on the web should be expected to understand "restore defaults" the same way), then you would instead register a definition for a new method token, pushing it through the standardization process and promoting adoption.
So it would be in this definition that we would specify, for instance, that the semantics of the method are idempotent but not safe, and also define any new headers that we might need.
there is a bit in it that conflicts with this idea of using POST to reset "The only thing REST requires of methods is that they be uniformly defined for all resources". If most of my resources are typical CRUD collections, where it is universally accepted that POST will create a new resource of a given type
There's a tension here that you should pay attention to:
The reference application for the REST architectural style is the world wide web.
The only unsafe method supported by HTML forms was POST
The Web was catastrophically successful
One of the ideas that powered this is that the interface was uniform -- a browser doesn't have to know if some identifier refers to a "collection resource" or a "member resource" or a document or an image or whatever. Neither do intermediate components like caches and reverse proxies. Everybody shares the same understanding of the self descriptive messages... even the deliberately vague ones like POST.
If you want a message with more specific semantics than POST, you register a definition for it. This is, for instance, precisely what happened in the case of PATCH -- somebody made the case that defining a new method with additional constraints on the semantics of the payload would allow a richer, more powerful general purpose components.
The same thing could happen with the semantics of CREATE, if someone were clever enough to sit down and make the case (again: how can general purpose components take advantage of the additional constraints on the semantics?)
But until then, those messages should be using POST, and general purpose components should not assume that POST has create semantics, because RFC 7231 doesn't provide those additional constraint.

Rest api with generic User

I created a few Rest apis right now and I always preferred a solution, where I created an endpoint for each resource.
For example:
GET .../employees/{id}/account
GET .../supervisors/{id}/account
and the same with the other http methods like put, post and delete. This blows up my api pretty much. My rest apis in general preferred redundancy to reduce complexity but in this cases it always feels a bit cumbersome. So I create another approach where I work with inheritance to keep the "dry" principle.
In this case there is a base class User and via inheritance my employee and supervisor model extends from it. Now I only need one endpoint like
GET .../accounts/{id}
and the server decides which object is returned. Also while this thins out my api, it increases complexity and in my api documentation ( where I use spring rest docs ) I have to document two different Objects for the same endpoint.
Now I am not sure about what is the right way to do it ( or at least the better way ). When I think about Rest, I think in resources. So my employees are a seperate resource as well as my supervisors.
Because I always followed this approach, I tink I might be mentally run in it and maybe lost the objectivity.
It would be great if you can give my any objective advice on how this should be handled.
I built an online service that deals with this too. It's called Wirespec:
https://wirespec.dev
The backend automatically creates the url for users and their endpoints dynamically with very little code. The code for handling the frontend is written in Kotlin while the backend for generating APIs for users is written in Node.js. In both cases, the amount of code is very negligible and self-maintaining, meaning that if the user changes the name of their API, the endpoint automatically updates with the name. Here are some examples:
API: https://wirespec.dev/Wirespec/projects/apis/Stackoverflow/apis/getUserDetails
Endpoint: https://api.wirespec.dev/wirespec/stackoverflow/getuserdetails?id=100
So to answer your question, it really doesn't matter where you place the username in the url.
Try signing in to Wirespec with your Github account and you'll see where your Github username appears in the url.
There is, unfortunately, no wright or wrong answer to this one and it soley depends on how you want to design things.
With that being said, you need to distinguish between client and server. A client shouldn't know the nifty details of your API. It is just an arbitrary consumer of your API that is fed all the information it needs in order to make informed choices. I.e. if you want the client to send some data to the server that follows a certain structure, the best advice is to use from-like representations, such as HAL forms, Ion or even HTML. Forms not only teach a client about the respective properties a resource supports but also about the HTTP operation to use, the target URI to send the request to as well as the representation format to send the data in, which in case of HTML is application/x-www-form-urlencoded most of the time.
In regards to receiving data from the server, a client shouldn't attempt to extract knowledge from URIs directly, as they may change over time and thus break clients that rely on such a methodology, but rely on link relation names. Per URI there might be multiple link relation names attached to that URI. A client not knowing the meaning of one should simply ignore it. Here, either one of the standardized link relation names should be used or an extension mechanism as defined by Web linking. While an arbitrary client might not make sense from this "arbitrary string" out of the box, the link relation name may be considered the predicate in a tripple often used in ontologies where the link relation name "connects" the current resource with the one the link relation was annotated for. For a set of URIs and link relation names you might therefore "learn" a semantic graph over all the resources and how they are connected to each other. I.e. you might annotate an URI pointing to a form resource with prefetch to hint a client that it may load the content of the referenced URI if it is IDLE as the likelihood is high that the client will be interested to load that resource next anyway. The same URI might also be annotated with edit-form to hint a client that the resource will provide an edit form to send some data to the server. It might also contain a Web linking extension such as https://acme.org/ref/orderForm that allows clients, that support such a custom extension, to react to such a resource accordingly.
In your accounts example, it is totally fine to return different data for different resources of the same URI-path. I.e. resource A pointing to an employee account might only contain properties name, age, position, salery while resource B pointing to a supervisor could also contain a list of subordinates or the like. To a generic HTTP client these are two totally different resources even though they used a URI structure like /accounts/{id}. Resources in a REST architecture are untyped, meaning they don't have a type ouf of the box per se. Think of some arbitrary Web page you access through your browser. Your browser is not aware of whether the Web page it renders contains details about a specific car or about the most recent local news. HTML is designed to express a multitude of different data in the same way. Different media types though may provide more concrete hints about the data exchanged. I.e. text/vcard, applciation/vcard+xml or application/vcard+json all may respresent data describing an entity (i.e. human person, jusistic entity, animal, ...) while application/mathml+xml might be used to express certain mathematical formulas and so on. The more general a media type is, the more wiedspread usage it may find. With more narrow media types however you can provide more specific support. With content type negotiation you also have a tool at your hand where a client can express its capabilities to servers and if the server/API is smart enough it can respond with a representation the client is able to handle.
This in essence is all what REST is and if followed correctly allow the decoupling of clients from specific servers. While this might sound confusing and burdensome to implement at first, these techniques are intended if you strive for a long-lasting environment that still is able to operate in decateds to come. Evolution is inherently integrated into this phiolosophy and supported by the decoupled design. If you don't need all of that, REST might not be the thing you want to do actually. Buf if you still want something like REST, you for sure should design the interactions between client and server as if you'd intereact with a typical Web server. After all, REST is just a generalization of the concepts used on the Web quite successfully for the past two decades.

REST API: returning newly create resource id?

In terms of good REST API design, is it a good idea to return id of the newly created resource? Say I have an API:
api/resource POST
I've seen some guru who has such API to return empty json and insert the URI into with Location header in response. I think returning
{ 'id': '1000' }
so that the caller can do something right away with it is better. Save one more round-trip to the server. What's the problem with this approach if any?
As requested I reposted my comment as an answer and added some more details to be worth an answer at all.
The common approach for creating new resources via HTTP POST method is to return a 201 Created status code. The response furthermore should therefore contain the current state of the resource as entity body and a location header pointing to the URI the resource can be found. Not doing so, may break some clients and prevent their correct interaction with the service. Clients here may be browsers, tailor made "languageOfYourChoice" applications or even other services.
In an ideal RESTful world, the client is only aware of one single URI to start with (like the entrance URI of the service, f.e. http://service.company.com/). The response of an invocation of that URI should return a document which can be understood by the client and contains further links the client can use if interested. This concept is similar to the big brother HTML and similar web resources used everyday by humans where links can be used to move from the start page to sub-pages or even external resources or other hyper-media resources. REST is just an abstraction and a generalization of the Web thing.
Although not part of the actual question and this is rather opinion based, there is an ongoing discussion among RESTful devolopers regarding the usefulness of common vs. specialized document types (mime types, ...). I think that there should be a standardized common REST-aware format for JSON, XML, ... Just plain application/json is not enough as this does not define how links and schemas have to be included. Even HAL is not descriptive enough (IMO) regarding executable actions on URIs and what document formats to expect on invoking those URIs and what arguments needed to be passed to the service.
Document formats (a.k.a media types) are one of the core concepts of Roy Fieldings acronym HATEOAS. Clients should not need any prior knowledge other than the entrance point and the media types understood by the clients (thus the previous paragraph). The possible actions are all described through following the HTTP protocol specification and knowing what the respective media types express.
Therefore, returning a URI instead of an ID has a couple of advantages:
URIs are per se unique, different vendors though may have identical IDs
Client needs no knowledge on how the server is creating those URIs, the server on the other hand can provide them almost for free. Returning a product ID of 1234 has almost infintly ways to be combined in an URI by the client - the client therefore needs special knowledge on how to create the URI so that the server is actually able to process the request correctly.
The server can move resources without the need of clients to change as clients (in an ideal RESTful world) would retrieve the URI of the resource within a further request' response. The client therefore needs only the semantical knowledge what the returned field acutally "means"

Designing RESTful URLs for web pages

Most REST tutorials arranged resources as following:
GET /car/ -> list of cars
GET /car/<id>/ -> info about specific car
POST /car/ -> create a new car
but when building web applications for use in browsers, there is a missing link that are rarely discussed, before you can POST to /car/, you need to GET a form for creating a new resource (car). What should the URL for this form be?
I typically used:
GET /car/new/ -> form for creating a new car
POST /car/new/ -> redirect to /car/<id>/ if item is created else show form with invalid fields highlighted
but according to http://www.slideshare.net/Wombert/phpjp-urls-rest this is not a good REST URL. I can see why it's not a good REST, because "new" is really used as a verb and not a resource, but where should the form be then, because GET /car/ is already used for listing cars, so you can't use GET /car/ for the form for new cars.
In short, my question is: "What is the RESTful URL for 'create resource form'?"
On a slightly related note, even in a web service, it is sometimes not always wise to rely on the client knowing the schema in advance, therefore even in web services there could be a need to be a way for client to request the resource's current schema. AFAICS, this as a similar situation with the need to GET a create form (i.e. the form is sort of like a schema which describes how to construct POST query for creating the resource). Is my line of thought here correct?
REST does not care too much about what your URI looks like as long as it identifies one unique resource and is self-describing. Meet those criteria, and beyond that, it is personal preference. Nothing prohibits using a verb in a URI if it makes sense to use one.
In regards to your slightly related note, what you hint at with the form being a schema is media type. RESTful architecture concerns the client and the server both understanding the media types used to represent the application state.
A REST API should spend almost all of its descriptive effort in
defining the media type(s) used for representing resources and driving
application state, or in defining extended relation names and/or
hypertext-enabled mark-up for existing standard media types. Any
effort spent describing what methods to use on what URIs of interest
should be entirely defined within the scope of the processing rules
for a media type (and, in most cases, already defined by existing
media types).
Read more here: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
That is from Roy Fielding, the man who defined REST. In general, your media types should be extensible -- that is, any changes should add on and not break older clients unless necessary.
I always assumed that "form" as such is not a resource, so /<name>/new is okay - forms are not usual elements of APIs. Author of the slides put that on a "bad" list, but didn't provide a correct one - I assume he was so RESTful that he forgot to think about such cases.