Though many question have been asked on nested urls and resources, I couldn't find an answer to this one:
I have two resources: user and blog.
A blog belongs to a user. A user can exist without any blogs.
I would like to create an endpoint that returns only users that have blogs (a distinct list).
I could use it to feed a select input on the front-end, to enable filter blogs per specific user, without listing users that don't have blogs.
What would be the URL for this endpoint?
/api/v1/blogs/users
or maybe
api/v1/users/?blogs=true
or something else?
First one looks less obvious. You want to GET users, right? Go get users, with some parameter-defined restrictions. They aren't part nor property of general resource named blogs.
Related
When it comes down to good RESTfull setup, what is the best practice for providing results that pertain to the owner as the requestor and results that pertain to a user wanting data owned by another user.
I have read that a resource should have max 2 base URLs so how to handle say,
Get all items for authenticated user
Get a single item for Authenticated user
Get all items for a particular user
Get a single item for a particular user
Although your question is a bit unclear, it seems to me you might mix up "Resources" as in HTTP resources, and Model objects or database rows.
The two do not necessarily have a 1-to-1 relationship, or even 1-to-2 relationship as you seem to imply. You can expose a database row in multiple "forms" as resources, there is no limitation how many times you can aggregate, transform or publish the same information, as long as those are all semantically different things.
So, back to your problem. You can publish resources pertaining to the authenticated user, and just users independently which might also contain the current user. With an URI structure for example like this:
/currentuser
/user/1
/user/2 <- might be the same as /currentuser
/user/3
...
There also could be a list of users recently logged in:
/recentuser/444
/recentuser/445 <- might be again /currentuser
...
That would be a third reference on the same user, but it is ok, because all of those have a different meaning, might even have different representations to offer (one might offer more information than others).
I understand, in general, the differences between GET and POST, and common use cases. This question is specific to actions that would toggle the state of something. For example, if users have the ability to "watch" (or "unwatch") a forum to be notified of changes, my inclination is to use a GET request to accomplish this, but is this something that is recommended to be a POST or a GET? Can using GET cause any issues in this case?
It won't create any issues, but it's recommended to use methods POST/PUT for create/update, GET for getting info and DELETE for deleting a record.
In your case I am thinking you have a relation between user and forum that handles the watching, unwatching a forum.. cause user can probably watch/unwatch multiple forums, in this case when he unwatches it you basically delete this relation between user and forum, so you'll need to do it via a DELETE method.
If you don't have a relation between users and forums, instead you keep the forum id in users table, unwatching would mean to update that user record, in this case you'd want to use PUT method.
http://www.restapitutorial.com/lessons/httpmethods.html
I understand that it's a good practice to only include in the URL the parameters needed to determine the object of the model.
If I have 2 models, Post and Comment... a Post has many comments and a comment belongs to one post. A URL for a comment can be
/comment/:comment_id
and from associations I can determine which Post it belongs to but
Some rails apps need to access external resources(Via APIs for example). If the rails app needs to replicate a part of another external source, what is the right way to handle URLs and routing?
If for example a post has some comments, The URL for a comment can be
/post/:post_id/comment/:comment_id
or
/comment/:comment_id
The latter has one disadvantage which is that I can't determine which post it belongs to if the API of the external source doesn't determine that and this would cause some problems with navigation through the app but it's a short URL and allows the user to easily manipulate the URL to get another comment(which I see as an advantage). At the same time using the first(long) link would make the URL so long but I can know which post it belongs to.
The only solution I can think of is to make both possible but the user would never know that the short one exists if I make the long one the default. What do you think?
I always use the longer / spelled-out version myself. I don't mind that it's long and I can only see good things come from it as you're discovering here. I also think it's an advantage because then you can do things like this:
post = Post.find_by_id(params[:post_id])
comment = post.comments.find_by_id(params[:id])
The point being that you can't go "comment fishing" this way. You have to have the right post context in order to get at a specific comment. This may not matter a whole lot if comments aren't at all sensitive, but there are many thing in a web app that may be. So scoping finds by a root object (like post here) allows a quick permissions check that can be reused and without having to check on parent objects.
Anyway, that's my 2 cents. I never understood why people take offense to the longer urls. If they work for you then don't be afraid to use them!
Sorry that I don't have the proper terminology to more concisely describe my database design question. Put in an example scenario:
User Charley logs onto a forum ("forum" merely as example app here), and before he is taken to the forum interface he must select which room he wants to go into. The only rooms available are "People into drama" and "People into scifi". Charley is dissatisfied with the selection, and has the ability to make his own room called "People into action", which he then choose to go into. "People into action" has the complete same forum interface as the other rooms, except is unpopulated.
User Franny logs onto the same forum app, and now sees there are 3 rooms, including the one Charley previous created. She could then also create her own room, or go into the room Charley has just created.
*For additional clarification, I envision /roomname1/forum and /roomname2/forum, where the forum is the same app with the same display and functions, but the posts it show would be different based on first part of the URI with roomname. What I have difficulty understanding is how to properly associate a post's post.room (given that a room has_many posts, and a post belongs_to a room) with what the first part of the URI where the roomname is identified.
I have just recently completed the Hartl's Rails Tutorial, and thought I'd get more experience making my own modifications to the default Twitter-like app. My goal here would be to set up these "rooms" where users could see the universe of microposts associated only with the "room" they are in, and not others.
Thanks for your help!
There are many ways you could do this, here is a quick high level that should get you started.
Create a model and controller (eg. Room/RoomsController)
RoomsController could be RESTfull
Define your routes
User goes to Rooms controller, index action and will see a list of rooms.
User can see all rooms and Add/Enter a Room (Enter could be your show action, add could be create)
You could build and add to this to enable users to delete/edit rooms they have created as a next step perhaps. You may want to associate posts, so they could belong_to for example. Hope this helps get you started!
I'm trying to figure out what the best way to show a list of members (users) that aren't a collection (group).
/users
is my route for listing all of the users in the account
/group/:id/members
is my route for listing all of the users in the group
/users?not_in_group=:id
is my current option for showing a list of users NOT in the group. Is there a more RESTFul way of displaying this?
/group/:id/non_members
seems sort of odd…
Either query parameters or paths can be used to get at the representation you want. But I'd follow Pete's advice and make sure your API is hypertext-driven. Not doing so introduces coupling between client and server that REST was intended to prevent.
The best answer to your question might depend on your application. For example, if your system is small enough, it may suffice to only support a representation consisting of a list of users and their respective groups (the resource found at /users). Then let the client sort out what they want to do with the information. If your system has lots of groups and lots of users, each of which belongs to only a couple of groups, your available_users representation for any group is likely to be only slightly smaller than the entire list of users anyway.
Creative design of media types can go a long way to solving problems like this.
Spoke with my partner. He suggested:
/group/:id/available_members
Seems much more positive.
The main precept of REST is "hypertext as the engine of application state". The form of the URI is irrelevant, what matters is that it is navigable from the representation returned at the application's entry point.