According to JSON API V1 specification and its recommendations, I know the URLs for collection of resources should be something like /photos. And the URL for reading, updating, or deleting a single resource that already exists in the database should be something like GET, PATCH, DELETE /photos/:id, for example.
But are there any URL requirements for rendering JSON data for resources to be created (i.e. the resource does not exist in DB yet and therefore it doesn't have id) yet. I know this is allowed in terms of the response data as section 5.2 says
Exception: The id member is not required when the resource object originates at the client and represents a new resource to be created on the server.
However, can the URL for rendering such a new object be like photos/new? As I'm using Ruby on Rails on the backend, photos/new is pretty typical.
Thanks!
The JSON:API specification is agnostic about URL design. But it defines how given URLs should be used. For creation of resources the URL, which represents a collection of resources of that type should be used:
A resource can be created by sending a POST request to a URL that represents a collection of resources.
https://jsonapi.org/format/#crud-creating
If you use /photos URL for a collection of photos, you should support creating another photo resource on that endpoint.
The server must assign an ID to a resource on creation unless client-generated IDs are used. It should also inform the client about the URL representing the newly created resource both through self link of the resource as well as Location HTTP response header. Going forward a client should use that URL to fetch the resource.
However, can the URL for rendering such a new object be like photos/new?
I'm not sure what you mean. A resource, which has not been created yet, can not be fetched from a REST API.
The term "render" is not that common for REST APIs. Do you refer to responding with a JSON representation of a resource as "rendering"? In this case a REST API cannot "render" the resource before it has been created by the client.
URLs of clients are independent from the URLs used by a REST API. A client could render a form to create a new resource on end-user facing URL /photos/new, while using the /photos URL of the REST API to create that resource.
Usually to create new object POST is using
You just pass resource attributes with request body. And you doesn't pass id
Modified example from your link
{
"type": "photos",
// no id here
"attributes": {
"title": "Rails is Omakase"
}
}
And path for such request is /photos
In monolithic Rails app /new is just page to create some resource, you don't need such GET-route in the JSON API
Related
In my Rails application I have an url routed to an action in charged of showing or creating (if not existing) e resource. What is the appropriate http verb to use for this kind of request?
To be more precise, in my method I don't directly access the resource but I use a library which has that behavior: first search and then create the resource if not exiting. My method, in the end, always provide the resource returned by the library either a brand new one or an old one. Hence I cannot split into two requests.
According to this and considering my method always returns the same resource (idempotent) it seems that PUT should be the right one. I just wonder whether PUT can be used in case where e resource is actually just retrieved (get) and anything is not even updated
tnx
POST for creating, GET for showing is automatically used by rails. But I hope you can do all sorts of things with custom programming as data will be available to you in form of params[]
According to Ruby on Rails guides, you should use GET and POST verbs. More information here: http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions
You use GET to retrieve.
If resource found return 200 with resource.
If resource not found let it return 404 and check the error code and use POST and create the resource.
If you donot need any parameter while creating resource then you should use GET request Else if you need params while creating resource , then you should make separate action for creating(Post request with params) and showing(GET request) resource.
Say that I have a Customers and an Orders tables, where each Customer may have many Orders.
Since in rails we are encouraged to represent these resources in a RESTful style, each of our resources, will respond to the following actions
index
show
edit
new
create
delete
So far, it all is very fair and plain. But now say that each time i open the show page of my Customer, i want to show a detail table containing all his/her orders.
This is a very common need, but doesn't this "unclean" the correctness of restful approach?
Is there some workaround, like "mashing" the two resources at a "view level", leaving them separate from the rest point of view?
Rails' default conventions ensure a RESTful application, and the only way this might become non-restful would be if you used custom-names on the routes, in which case you would have you add an extra bit of code to specify the HTTP method.
So, to accomplish what you're suggesting, at the view level, you may have something like this:
app/views/customers/show.html.erb
....
<% if customer.orders.any? %> #the orders method is provided on `customer` by defining the `has_many` and `belong_to` associations
<%= render #orders $>
And you would make sure to define #orders in the show action of the customers_controller.rb file.
This not only is RESTful, but also works within Rails' default conventions.
Those actions you list are not what makes something RESTful. There are a bunch of characteristics an application must have to be considered RESTful. Some of these characteristics are:
it is thought of as a repository of resources
resources are identified by a URI
there is a uniform interface for interacting with resources - the HTTP verbs of GET, POST, PUT, DELETE, etc.
Rails takes care of receiving HTTP requests and calling your application's functionality, regardless of whether it is RESTful in nature or not, through routing. Rails routing takes those HTTP verbs I mentioned, in combination with a URI, and determines which controller to call. By default Rails follows the RESTful paradigm, and by convention will map verb/URI combinations to those actions you listed - but the actions themselves, and the fact that they are lumped into a single controller, are not part of REST - they are just the rails convention.
In fact, the rails default routing maps 4 different resources to that single controller and its actions:
/customers // the list of all customers, GET/POST -> index/create
/customers/new // a form for creating a customer, GET -> new
/customers/{id} // a single customer, GET/PUT/DELETE -> show/update/destroy
/customers/{id}/edit // a form for editing a customer, GET -> edit
Resources can contain sub-resources, and Rails completely supports that. A sub-resource might be:
/customers/{id}/orders // the list of all orders for a particular customer
Another key part of REST is that it supports a resource having different representations, whether that is HTML, XML, JSON, etc. Clients use HTTP headers to convey what representation they are passing into the app (using the Content-Type header) and (usually) what they will accept in response (using the Accept header).
Its up to the application to determine what a resource representation looks like. Typically a resource will either be "thin" or "fat". A "thin" resource is one that simply has links to its sub-resources and further calls must be made to get them. A "fat" resource will contain the fully-fleshed out sub-resources it contains. Typically with an HTML representation, an application will return some form of "fat" resource. There is nothing non-RESTful about this - and is exactly what you are describing you want for your application.
So that was my long way of saying "don't be afraid of not being RESTful by displaying sub-resources - it's perfectly OK" :-)
I am writing server end of a JavaScript app. But engineer who write js and design APIs of this app decided all of ajax send json data to "one" URL, like this:
{
"id":"...",
"method":"method_name",
"params":{...}
}
So, I must provide different service for different "method_name". And the Rails router can not address this problem.
I can use the Object.send method routes the different service to different method, but, I want to distribute my code to different Controller class.
Can I parse the json data in route.rb file? Then route the /url/method_name to controller/action ?
I am integrating with a 3rd party API (echosign) and one of the things I need to specify is a callbackURL.
"A publicly accessible url to which EchoSign will do a HTTP PUT operation with the final signed PDF. HTTP authentication is supported using standard embedded syntax - i.e. http://username:password#your.server.com/path/to/file. EchoSign can also ping your system using HTTP GET every time there is a new agreement event. Please contact support#echosign.com if you wish to use this option."
How would this work in rails?
I was going to expose a controller method. Would this need to be PUT method?
How would I access the contents of the file?
Yes, you need to provide a put route to an action that will consume the upload.
Check http://guides.rubyonrails.org/form_helpers.html#what-gets-uploaded for the upload action
Enter s.th. like the following to your config/routes.rb to add a PUT Route to the eccording controller..
match '/mycallbackurl' => 'MyEchoController#upload', :via => :put
just a short question:
Having the new instance of a model and issuing a model.save() with URL set to /api/store/category, Backbone issues a POST. According to my knowledge, it should use PUT, like mentioned in this "PUT or POST: The REST of the Story" blog post.
Who is right? BB or this article's author?
According to Backbone documentation, saving a new model will result in a POST request, and saving an existing model (having an id) will emit a PUT request.
save model.save([attributes], [options])
...
If the model isNew, the save will be a "create" (HTTP POST), if the model already
exists on the server, the save will be an "update" (HTTP PUT).
And if you are wondering if Backbone should use a POST for creation, check
PUT vs POST in REST
RESTful web services on Wikipedia
In the light of these articles, I'd say that, in the context of Backbone, the verbs are correctly used:
saving a new model causes a change in the system, a new URL is added, the action is not idempotent, it should be a POST,
saving a known model replaces a resource at a given URL, the action is idempotent, it should be a PUT.