ReSTful design: return an empty object as a template for create new form - rest

My question is straighforward - I think.
Currently the following Uris exist:
http://someserver/service/item GET returns all items
http://someserver/service/item POST creates a new item
http://someserver/service/item/{id} GET returns item with id {id}
http://someserver/service/item/{id} PUT updates item with {id}
What I would like to do is return a blank 'item', like a template for creating new items which contains a list of the object parameters, their types, required or not. The reason for this is I would like to build a generic jquery 'create new' plugin completely ignorant of the data structure, which I could apply to all my new objects.
What is the best way to implement this?
I hope this makes sense and thanks for your time.

I understand an answer provided by Darrel but I would respectfully argue against it.
It seems to me that this template object (resource) is an important part of your application because you want to make it generic. It's a first class citizen resource and we're talking about REST, so it should be given a corresponding treatment. I should be able to GET the template resource, it shouldn't be "hidden" behind POST.
GET http://someserver/service/item/template
Then you can also introduce versioning and variability much more easily when you have a resource accessible via GET.

I do pretty much the same thing. I include a link in my "list of items" resource that you can POST to. The response is a template of a new item. Arguably you could also do a GET to retrieve the template, but I use the opportunity to assign a new Id to the item so my request is not idempotent.

Related

Is it possible to make the same field compulsory for POST and optional for PUT requests?

Is it possible to make the same field compulsory for POST and optional for PUT requests for REST API? Or it depends on teqnology used to implement this request?
For example, there is a POST request to create Car objects and this object has a field model_id which is actually chosen from a dictionary of models. And the POST request requires model_id because the car must have model_id defined.
And I want to have a PUT method which changes some field e.g. serial_num, manufacture_date, color etc. even model_id. But I want this PUT method to change model_id as optional parameter, e.g. I just want to change color and it is Ok.
So is this possible in REST? Does some technologies that implement these request could not allow me to make different set of optional/compulsory params for POST ant PUT?
Well, you can do whatever you want here. Nobody will kill you if you check fields in the request body and return an error if model_id is specified (or not).
Some guys use POST method to update entities in API.
If you want to be closer to standards better use PATCH for partial updates.
You can find a lot of interesting info here:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
Use of PUT vs PATCH methods in REST API real life scenarios
https://www.rfc-editor.org/rfc/rfc7231#section-4.3.4
https://www.rfc-editor.org/rfc/rfc5789
One important thing from 4. source:
The PUT method is already defined to overwrite a resource with a
complete new body, and cannot be reused to do partial changes.
And another one sentence from 3. source:
Generally speaking, all implementation details behind the resource interface are intentionally hidden by the server.

Can the Post for a ODataContoller in WebAPI 2 take an IEnumerable of a complex object

I want to know if passing a collection to the post of an ODataController is even possible before I waste my time trying to figure out where my problem is.
I've seen variations of this question over the internet, but nothing that has led me to an answer.
I created the Post method on an ODataContoller where I want to pass in a IEnumerable of a complex object. However, when I debug the controller, the parameter is null.
When I take each individual element of the collection and pass it into a Controller's Post (that takes a single object), the object is accepted. So I know the individual objects are being formatted correctly.
Technically this is possible. If you get null as complexObjects in the following call
[HttpPost]
public IHttpActionResult CreateMany([FromBody] IEnumerable<ComplexObject> complexObjects)
{
// ...
}
it's probably due to a format error in the bodies json object. If you have a working single object you can post, you just need to wrap it in brackets ... an array is an array even if it cotains only one element. This assumes, you check your web api actions via postman, fiddler etc., where you can 'compose' the entire request. Alternatively you can use the output of a 'GET all' action (if you have one) as input.
Regarding another aspect, the REST-fulness of list creation, you may find RESTful way to create multiple items in one request interesting
Hope this helps.

Moving child resource to another parent in REST

I have a REST service.
And now I need to have functionality to move some child resources from one parent to another, for example move a book from one author to another.
My variant is:
POST /api/books/x/moveto/y
But how to create such architect the RESTful way?
From a REST point of view, URLs should be used to locate the resources rather than expressing operations. To express operations, the existing HTTP verbs should be used.
Looks like your "move" operation is all about replacing the author of the book.
And the PUT method seems to be the way to go:
4.3.4. PUT
The PUT method requests that the state of the target resource be
created or replaced with the state defined by the representation
enclosed in the request message payload. [...]
So, you can have an endpoint like the following:
PUT /api/books/{bookId}/author
And the request payload will contain a representation of the new author.
I think in this case updating the author as suggested in Cassio's answer is a good solution. For less obvious "actions" I use PATCH endpoints. Consider archiving a book:
PATCH /api/books/{bookId}/archive
The intent is obvious -- archive the book with this identifier. For more complex actions, include a body or use a query string parameter. For instance, moving a book out of one category and into another (assume a book can have 0-many categories):
PATCH /api/books/{bookId}/move
{
fromCategoryId: 100,
toCategoryId: 200
}
Or:
PATCH /api/books/{bookId}/move?fromCategoryId=100&toCategoryId=200
In the end, IMO, what matters most is readability and consistency. There is not necessarily a "right" way to do this sort of thing.

REST - basic principles - Where to put the new and edit words

I'm wondering where to put the edit, and new keywords by rest application. I'll use express-resource in a project, and the default settings are these:
GET /forums -> index
GET /forums/new -> new
POST /forums -> create
GET /forums/:forum -> show
GET /forums/:forum/edit -> edit
PUT /forums/:forum -> update
DELETE /forums/:forum -> destroy
There is a problem with this solution: there is not a real resource behind the new and edit. I mean the URL-s refer to resources, and after any slash is a sub-resource.
For example:http://my.example.com/users/1 represents:
var firstUser = {
name: "John Smith",
birthDate: new Date(1952,10,4),
hobbies: ["skiing", "football"],
...
}
And http://my.example.com/users/1/birthDate represents:
firstUser.birthDate
But by http://my.example.com/users/1/edit there is no such property:
firstUser.edit
So something is wrong with this conception.
Where is the real place of these keywords? In queryString or in headers?
From the perspective of a REST API these do not exist anywhere as they are not related to the representation of resources. They are actions upon resources and therefore expressed by the HTTP methods used. They would not bee needed if you were to create an external client that uses the API.
There is likely a need to provide some support for this type of functionality so that something like a UI could be presented, but that is the concern of the particular application and not the API itself. At that point it becomes discretionary but I would certainly avoid using headers as that would be pretty outside of conventional practice. But by headers it appears that you actually meant URI path. Out of those 2 I would say the path is the better option since it clearly defines any type of UI as a distinct resource and would keep it apart from the clean API, while using a query string on a part of the API would more tightly (mistakenly) associate it with the underlying resource.
Some update after a year or so:
edit and new should be hyperlinks
these links are just the representations of possible operation calls
by following them it is possible to manipulate the resource they belong by sending representations of the intended resource state, and/or by calling the proper methods
these terms are no resources, they don't have their own URL (resource identifier)
Thanks the advices Matt Whipple!
I think the best way to learn REST is reading the Fielding dissertation. There are many tutorials out there, but the authors of most of these does not really understand REST.

Proper way to construct this REST URI?

I want to have a REST resource for Foo and I want to be able to perform a POST to create a new Foo.
Foos can only be of two subtypes - Fizz and Buzz (the models are FooFizz and FooBuzz on the backend and both extend Foo). All Foos are either a Fizz or a Buzz. Most of the other models follow this pattern too (generic with subtypes for Fizz and Buzz). For the short and medium term, there will not be a new type added to Foos. In the long term it's more likely that this application will be obsolete before a new type is added, but the possibility exists.
At any rate, here are some URI schemes I came up with for working with Foos.
POST /foo?type=fizz
POST /foo/fizz
POST /fizz/foo
POST /foo-fizz
POST /foo/{foo-id}/fizz
My thoughts on this:
(1) might be unnecessary client-server coupling since it's dependent on the query string being properly formed. But it makes the most sense to me.
(2) and (3) are undesirable because you want to be able to have the URI go /foo/{foo-id} for performing operations on an individual Foo.
(4) requires Fizzes and Buzzes to become completely separate branches of the URI tree
(5) seems like a decent scheme although it might mess up the URI tree.
I'd be strongly tempted to just have a POST to /foo with the type of foo to be created (fizz or buzz) being determined by the contents of the document being POSTed. It would respond with a suitable redirect to the URI for the newly created foo (/foo/{fooId}, presumably) through which you'd manipulate things in the normal way.
Admittedly, I am not a REST expert, however here are my two cents.
Why would you even have a post to foo/{foo-id}? In that case, it would be more of a PUT for an update. The only time you would need to post would be if the id was being auto-created and unknown until actually created. So, in that case, I would lean towards 1 as you are creating a foo and the rest is just information needed to create foo. After that point, would you even need to care about the subtype (fizz or buzz)? I would assume the foo/{foo-id} would be enough information to work on it individually and determine the type from it.
So:
POST /foo?type=fizz
**You could possibly even remove the query string and send it in as your creation data, but that is up to you
GET /foo/{foo-id} ...retrieve the created foo
PUT /foo/{foo-id} ...update the created foo
DELETE /foo/{foo-id} ...delete the created foo
That is what I would do at least.
<soapbox>If you are really doing a RESTful architecture, then you shouldn't need to ask this question</soapbox>.
RESTful architectures include links in the representation that direct the flow of the application. If you are creating a new resource that is a child of a parent resource, then the representation of the parent resource should have an embedded link that tells you what URL and (potentially) which verb to use. Something like:
<link rel="add-child" method="POST" href="http://foo/1234">Add a new child</link>
If you are creating a wholly new root resource then, you probably want to POST to an absolute URL and have either the response document or Location header tell your application where to retrieve a new representation from. The target resource is essentially the "entry point" into your application's state machine.