I'd like to implement a valid Restful API.
I have a resource called "Jobs" and also I implemented CRUD [GET, POST, PUT...] for example: GET: /api/jobs/1 or POST: /api/jobs/ with a body {...}
Now I'd like to add a method to start a job number 1234.
How can i implement this? what should be the URI? What should be the HTTP verb?
Can someone give me an example
You can create a new resource
POST /started-jobs?jobId=1234
You can edit the state of the job inline:
PUT /jobs/1234
{
"state": "started",
..
}
You can use a micro-PUT
PUT /jobs/1234/state
started
That's just off the top of my head. There are surely other options. Which one is best? That requires more information on what you're trying to accomplish.
Related
I want to develop restful API related to user authentication. please suggest if my URL designs looks ok. as a background information, these API use an LDAP directory such as microsoft AD.
user registration
POST /auth/register
payload : {username: "", password: ""}
user login
POST /auth/login
payload : {username: "", password: ""}
password change
PUT /auth/password_reset
payload : {username: "", old_password: "", new_password:""}
deactivate user
DELETE /auth/de_activate/{user_name}
activate a user
PUT /auth/de_activate/{user_name}
I do understand that I am using verbs in the URL. However, since these APIs create some resource [register API] as well as perform some actions [login api], I went ahead with the URLS above. I would appreciate any inputs through.
Regards
Prasad Katti
These are the changes I would make. I know that you know already that the URL paths should be nouns and your verbs should be GET, POST, DELETE, etc. to indicate that you want to view, create or delete a resource.
Instead of:
POST /auth/register do POST /registrations
Instead of:
POST auth/login do POST /logins or POST sessions
Your password reset route is okay, but I don't believe the action matches the resource.
Instead of:
PUT auth/password_reset do POST /password_resets
And yes, PUT actions are supposed to update or replace the resource, but what other resources do you have that require you to send the old and new values? The one above is still accurate, since you are creating a "password reset" which sets off a workflow of actions that may require people to check their email and click a link, but I think that doing PUT /passwords is misleading due to the payload that is required.
Instead of:
DELETE /auth/de_activate/{username} do DELETE /users/{username} or DELETE /users/{userId} or even PUT /users/{username} with {"active": false}. Personally, I think that hard vs soft deletes should be transparent through your API though.
And instead of:
PUT /auth/de_activate/{username} do PUT /users/{username} with {"active": true} or POST /users/{username}/reactivations.
The purpose of RESTful standards is to make a consistent and predictable API for clients. All it is really is a set of guidelines. It's not super-strict or anything so ultimately it's left up to your best judgement. These are just the adjustments I would make.
I want to use angular resource to interact with my rails backend, the build-in $resource service is not fully compatible with rails API, like PUT is not support by default, I have to add custom action "update" with PUT method.
This problem with this approach is I have to add update action for every resource to make angular resource align with the rails API backend.
Is this the good approach to go?
I also found a angular resource wrapper angularjs-rails-resource, which provide a update method with PUT http verb, but it seems like the way how it handle parameters passing is a bit odd. for example, it wrap the parameter with a "undefined" key.
Parameters: {"undefined"=>{"username"=>"xxxx"}, "version"=>"1", "id"=>"88"}
So, the question is what is the best practice to use angular resource with rails API?
If you don't want the overhead of restangular and just want to add the update method to every resource, you can simply add a decorator to the $resource service.
Something like this:
.config(function ($provide) {
$provide.decorator('$resource', function ($delegate) {
//Store the delegate, so we can access it later
var resourceFactory = $delegate;
//Add the actions that you want added to each Resource here
var default_actions = {'update': {method: 'PUT'}};
return function (url, paramDefaults, actions) {
actions = angular.extend({}, default_actions, actions);
return resourceFactory(url, paramDefaults, actions);
};
});
})
Use angular-rails-resource. It is optimized for the Rails philosophy, which means that you don't have to juggle around with request/response format by yourself. And it supports a lot of other cool features, like nested resources, automatic name conversion, etc...
Take a look on restangular. It's really a nice solution for interacting with rest api.
I'm working on REST API, and I trying to understand whether this looks legit in terms of REST.
I've players which using some mobile app with a login mechanism,
So the question is, if the player needs to update some attribute on his resource,
How the URL & PARAMS should looks like:
Option #1:
PUT /api/players/59/
PARAMS { some_attribute: "some_value" }
Option #2:
PUT /api/players/self
PARAMS { some_attribute: "some_value" }
The thing is, that the player doing the call with authentication, so it looks odd that he needs to send his id, it feels like he can send update on some other id, so when he sends 'self' it looks more suitable but uglier.
What's the REST point of view here?
Or maybe another option?
You should use first option
But in first option, request additional parameter like authentication_token
to verify the user and user is updating his information only.
This gist will help you in authenticating user
https://gist.github.com/josevalim/fb706b1e933ef01e4fb6
It shows 2 method for authenticating user while communicating with API
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.
I'm doing a rewrite of an old Rails application and I thought I should do it in a RESTful manner, as a learning experience if nothing else.
I've reached some actions that toggles a boolean value, for example if an article is published or not.
Before I had a couple of actions: toggle_published, publish and unpublish.
They were very easy to use: i just made a link to them in the article-list.
How would you do the same thing in a RESTful manner?
Should I use the update-action, and build a mini-form to replace each link that I used before? I don't particulary like that idea.
Just a notice:
A toggle method is not RESTful, because the HTTP PUT verb is supposed to be idempotent (see a.o. http://en.wikipedia.org/wiki/Idempotence#Examples). This means that no matter how often you execute a method, it should always give the same result. A toggle method does not adhere to this principle, as it does not give the same result if you execute it once comparing to executing it twice.
If you want to make it RESTful, you should create two methods: one for setting and one for unsetting.
Making an application RESTful does not only mean that you should use the correct HTTP verb.
I'd probably solve it with PUT/DELETE or POST/DELETE on a nested "toggle resource". Perhaps not 100% completely restful but certainly easy enough to understand.
PUT or POST /articles/:id/published # Toggle published ON
DELETE /articles/:id/published # Toggle published OFF
GET /articles/:id/published # Get state RESTfully via status 200 (ON) or 404 (OFF)
Might seem a bit odd, but it is technically RESTful.
Update: A (perhaps) more natural approach might also just be:
PUT or POST /articles/:id/published Data: { state: true/false } # Toggle published ON
You could also use the PATCH verb with the actual article which I assume has a published property:
PATCH /articles/:id { published: true/false }
Because all the cool REST kids are using PATCH nowadays.
It sounds like you have two use cases:
set published state
toggle published state
You should be able to add a member route for the toggle action for:
/articles/<id>/toggle_published - calls Article.toggle(:published)
And use Article update on :published attribute via the standard REST resource route.
map.resources :articles, :member => :toggle
I like #Van der Hoorn answer
so in real life we are using in login & logout scenario
use post or put or patch
/users/login -> with some payload data
/users/logout
In Above Eg login & logout is almost acting like setting boolean Flag , Easy to read and set in db
Eg : so its no harm to use same idea in toggle context
use post or put or patch
/book/3/publish
/book/4/unpublish
Note . :
1 : use this approach if there is only 1 field to be toggled , else if there are multiple fields then general /book/4 a patch request with payload data will do
2 : use this approach if there is any security layer is implemented so it will be like
Eg :
Editor -> can access urls like `/books/:id` & `/books/:id/publish`
Senior Editor -> can access urls like `/books/:id` & `/books/:id/unpublish`