I am using ember-rest in my application for persistence layer, and it has been working great. One of the resources that I am working with, requires some optional resource parameters. Looking at the ember-rest source code, I couldn’t find anything related to setting request parameters, but it is possible that I overlooked something.
My question is, does ember-rest provide a way to specify request parameters to be appended to the URL? If not, some advice about how I should add this functionality to ember-rest would be very appreciated.
For example, I am working with a resource called blocki which comes with the following REST api:
POST /api/apps/:app_id/blockies?parent=:parent_id
- default :parent_id=:app_id
- TODO: error if the blocki cannot be placed in :parent_id
PUT /api/blockies/:id
PUT /api/blockies/:id?parent=:parent_id
- update the blocki and reparent it
DELETE /api/blockies/:id
As you can see when I do a put request to update this resource I can optionally pass a parent_id if I want to update that. I want to achieve this using ember-rest.
You can completely customize the url for a resource or resource controller by overriding the _resourceUrl() method. For instance:
_resourceUrl: function() {
return this._super() + '?parent=' + this.get('parent_id');
}
Related
I am new the ember , what is the difference between memberAction and collectionAction in ember-api-actions.
i know these are used to get response data from backend . thanks .
A member action happens on a specific resource and a collection action happens on the whole collection. For instance, POST /users/sync is a collection action and POST /users/1/promote is a member action.
You might also find Ember Custom Actions of use for this kind of thing.
I'm converting my app over to the new version of ember-data (1.13.5).
I'd like to be able to request a set of resources (e.g. this.store.findAll('post')), maintain the background reloading behaviour that comes out of the box, but also request that a set of related resources be included from the server.
i.e. something like:
this.store.findAll('post', { include: ["comments"] }
This can obviously be done with a query, but I'm assuming that kills all of the background reloading stuff?
I think what you are trying to do is sideload your comments together with the post.
I don't know how your server code for that is written, for instance in my case where I use laravel for the serverside,
I would check for the include parameter in the controller code for retrieving the post. If include comments directive has been specified, then I would take advantage of a builtin mechanism that laravel provides where you specify whether you want a model with its related models, i.e return post->with('comments');
And then with the help of a custom json serializer, you can extract the comments and add to the json for the post .
But outside of laravel, an algorithm like this would do in the serverside code for retrieving posts
Retrieve all the posts.
Check for the include parameter. If it's specified, retrieve the comments that belong to each post.
Then write code that creates a json result merging the json result for post with its comments together.
The goal
No log in screens!
A visitor to the site should be able to create a widget without logging in.
This widget is publically accessible and can be shared via a short URL.
To edit this widget, you need to know the longer, administration URL.
The show action should have a URL with a short token instead of an id:
widget_path(widget) # => /widget/abc123
The edit action should have a URL with a long token instead of an id:
widget_path(widget) # => /widget/abcdefghijklmnop123/edit
What I have so far:
Generating tokens
I'm using a before_create callback to generate two tokens, a token and an admin_token with SecureRandom.urlsafe_base64.
Then, to change the URL helpers from generating URLs with the id, I override the to_param method in the model to return the token:
def to_param
token
end
Now when I save a new record, a token gets generated and the url helpers return these:
widget_path(widget) # => /widget/abc123
edit_widget_path(widget) # => /widget/abc123/edit
The problem
I need the edit_widget_path helper to use the admin_token field.
I can't seem to find a way of doing this.
In an ideal solution, I would want the _url versions of these to also work and they should be available in the usual places (controllers and views).
The closest I have found is to create custom _path and _url methods in ApplicationController, but this doesn't seem right.
Open to suggestions for how to achieve this.
Is there a way to use Rails' existing mechanism for generating URL helpers?
I hope that makes sense, feel free to ask for clarification.
Thank you!
I don't know of any rails mechanism that could handle that except inheritance. You could implement a subclass and override the to_param method there. I don't think that this is worth doing so, since you just want to handle 1 route here. I think I would just create a helper method to handle that case.
Another hint here: You could use the same mechanism that GIT uses. Create a UUID (long version) and use the first X digits to make the public url, just the full UUID is secret. This works in GIT 99,9% of the time without collisions, so it should work for you as well.
I'm curious to learn more about RESTful design patterns around the PUT call. Specifically, am I violating norms by changing the resource ID as part of a PUT call?
Consider the following...
POST /api/event/ { ... } - returns the resource ID (eventid) of the new event in the body
GET /api/event/eventid
PUT /api/event/eventid - returns the (possibly new) resource ID depending on request body
GET /api/event/eventid - fails if the original eventid was used in the URI
The endpoints for GET and PUT can quickly access the resource if the eventid represents internal resources (like a database record). If the PUT results in the server moving the underlying resource, the ID can change.
Am I violating norms when I do this?
REST is not a strict specification, but more a set of guidelines and best practices that can be followed to build web-services that are easy to understand and work with. So there's nothing that prevents you from changing a resource IDs during a PUT.
That being said, doing so is IMO a bad practice. One of the ideas behind REST is that each resource can be referenced using a URI. In your case this URI is the concatenation of the path and (I assume) an internal ID. This URI could be used by other "systems" and stored as references. If you change the ID of a resource on a PUT, you change the URI and all references to that resource will be broken (404).
If you feel the need to change the ID that is part of the URI, you may not have picked the right property for it. Consider something else that would be immutable (e.g.: tag your resource with a UUID and use it rather than an internal DB ID).
Not addressing your question full on, but this makes me worry:
returns the resource ID (eventid) of the new event in the body
You aren't returning an integer id, and then letting the client construct urls from this, are you? A proper REST application should give url's to resources, not ids.
As for your question - PUT means something like "Create a new resource at this location". You could conceivably reply with a redirect and a Location header, but it's a bit of a strange thing to do. Besides, the semantics of PUT dictates that you send the entire entity with the request, which is probably not what you want in this scenario. Maybe it would be more fitting to use POST in this situation? (E.g. POST on /api/event/1234
I think it's ok; PUT is still idempotent (repeated calls will not lead to other modifications).
Just: I would ensure that the old ID is not reused, and have the api return 301 codes for calls to old ID (in case other clients had links to the resource).
Maybe the initial PUT that modifies the ID should return a 303 code that point to the new resource location, I'm not sure here.
I have the following Url which returns me the list of resources:
http://example.com/resources/
I also implemented a method which returns a specific resource (in this case, the resource 142).
http://example.com/resources/142
I would like to add a method which is outside the typical HTTP method: List, Create, Retrieve, Replace, Update. What is the pattern to follow? In my specific case, I need to check the availability of resource. How would the Url look like (http://example.com/resources/checkavailability/142)?
I though about simply using the GET method and retrieve that information as part of the object returned. However, some of my colleagues argue that this would not be efficient (the data to transfer would be much bigger than just returning true/false).
Thanks for the help!
There is no need for a resource to check the availability of another resource, and there is no need for a GET request, a HEAD request should be enough, this is the same as a GET request but without transferring the body. You can then look at the return codes, and via those determine if the resource is available. This is assuming you have properly implemented return codes.
Restful over HTTP gives you uniform interface, you often don't need to encode the actions inside your URL
Regarding your mentioned /checkavailability using GET returning payload inefficiency is a valid reason, so use HEAD (it only gives you back the response headers).
request:
HEAD /resources/123
response status:
404 Not Found: equals to /checkavailability == false
200 OK: equals to /checkavailability == true
Other suggestions uniform interface replacements:
/resources/list : GET /resources
/resources/replace/123: PUT /resources/123
/resources/update/123: PUT /resources/123
/resources/create: POST /resources