RESTful route for a list of members that are not in a collection - ruby-on-rails

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.

Related

MVC Web Api Differentiate between user and public data in RESTful approach

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).

How can I get the participants of a Vanity experiment?

tl:dr
Is there anyway to get something like Vanity.experiment(:landing).participants_for_option(:a) returning a array of users?
The long story
I'm using the gem Vanity with a Rails 4.2 application and it is working nicely, but I want to inspect further the behaviour of participants.
I tested what kind of page converted more users: A classical signup page versus a signup with order page. The classical signup page led to almost three times more signups, but I'm still in the dark in the sense that I don't know, among the signup-only-users, how many ordered a product.
It sounds like you're trying to understand more about how an experiment affects different parts of your funnel.
At the aggregate level, one way to do that may be to to use multiple metrics for your experiment at different parts of your funnel, e.g. track!ing both signups and then purchases.
Unfortunately, Vanity isn't set up very well to query for individual participants per alternative, because testing itself is aggregate. If you want to access alternatives per user, there are methods for that, for example, Vanity.playground.adapter.ab_showing(experiment, identity), see the docs.
If you're interested in doing more in depth analytical queries, it might be worth using the SQL adapter, the schema tracks per participant and you could join to other tables that hold data about purchases/etc.
Edit:
It looks like this has changed in the most recent version of Vanity:
https://github.com/alobato/vanity/blob/master/lib/vanity/playground.rb#L231
Vanity.playground.connection.ab_assigned(experiment_name, identity)
Vanity.playground.connection.ab_showing(experiment_name, identity)

How do you decide how much data to push to the user in Single Page Applications?

Say you have a Recipe Manager application that you're building with a Web Api project. Do you send the list of recipes along with their ingredient names in JSON? Or do you send the recipes, ingredient names, and ingredient details? What's the process in determining how big the initial payload should be for a SPA?
These are the determining factors in how much to send to the client in an initial page:
Data that will be displayed for that first page
Lookup list data for any drop downs on that page
Data that is required for and presentation rules (might not be displayed but is used)
On a recipe page that would show a list of recipes, I would get the recipes and some key factors to display (like recipe name, the dish, and other key info) that can be displayed in a list. Enough for the user to make a determination on what to pick. Then when the user dives into a recipe, then go get that 1 recipe's details.
The general rule is get what you user will almost certainly need up front. Then get other data as they request it.
The process by which you determine how much data to send solely depends on the experience you want to provide your users - however it's as simple as this. If my experience demands that I readily display all of the recipes with a brief description and then allow them to drill into the recipe to get more information, then I'm only going to send enough information to produce the display and navigate further into the entity.
If then after navigating into the recipe it requires that you display the ingredient names and measures then send down that and enough information to navigate further into any single ingredient.
And as you can see it just goes on and on.
It depends if your application is just a simple HTTP API backing your web page, or your goal is something more akin to Platform As A Service. One driver for the adoption of SPA is that it makes the browser another client, just like an iOS or Android app,or a 3rd party.
If you want to support multiple clients, then it's likely that you want to design your APIs around the resources that you are trying to expose, such that you can use the uniform interface of GET/POST/PUT etc. against that resource. This will means it is much more likely that you are not coding in an client specific style and your API will be usable by a wide range of clients.
A resource is anything you would want to have its own URN.
I would suggest that is likely that in this case you would want a Recipe Book resource which has links to individual Recipe resources, which probably contain all the information necessary for that Recipe. Ingredients would only be a separate resource if you had more depth on what an Ingredient contained and they had their own resource.
At Huddle we use a Documentation Driven Design approach. That is we write the documentation for our API up front so that we can understand how usable our API would be. You can measure API quality in WTFs. http://code.google.com/p/huddle-apis/
Now this logical division might not be optimal in terms of performance. Your dealing with a classic tradeoff (ultimately architecture is all about balancing design tradeoffs) here between usability of your API and the performance of your API. Usually, don't favour performance until you know that it is an issue, because you will pay a penalty in usability or maintainability for early optimization.
Another possibility is to implement the OData query support for WebAPI. http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api
That way, your clients can perform their own queries to return only the data they need.

MongoDB and embedded documents, good use cases

I am using embedded documents in MongoDB for a Rails 3 app. I like that I can use embedded documents and the values are all returned with one query and there is less load on the database server. But what happens if I want my users to be able to update properties that really should be shared across documents. Is this sort of operation feasible with MongoDB or would I be better off using normal id based relations? If ID based relations are the way to go would it affect performance to a great degree?
If you need to know anything else about the application or data I would be happy to let you know what I am working with.
Document that has many properties that all documents share.
Person
name: string
description: string
Document that wants to use these properties:
Post
(references many people)
body: string
This all depends on what are you going to do with your Person model later. I know of at least one working example (blog using MongoDB) where its developer keeps user data inside comments they make and uses one collection for the entire blog. Well, ok, he uses second one for his "tag cloud" :) He just doesn't need to keep centralized list of all commenters, he doesn't care. His blog contains consolidated data from all his previous sites/blogs?, almost 6000 posts total. Posts contain comments, comments contain users, users have emails, he got "subscribe to comments" option for every user who comments some post, authorization is handled by the external OpenID service aggregator (Loginza), he keeps user email got from Loginza response and their "login token" in their cookies. So the functionality is pretty good.
So, the real question is - what are you going to do with your Users later? If really feel like you need a separate collection (you're going to let users have centralized control panels, have site-based registration, you're going to make user-centristic features and so on), make it separate. If not - keep it simple and have fun :)
It depends on what user info you want to share acrross documents. Lets say if you have user and user have emails. Does not make sence to move emails into separate collection since will be not more that 10, 20, 100 emails per user. But if user say have some big related information that always growing, like blog posts then make sence to move it into separate collection.
So answer depend on user document structure. If you show your user document structure and what you planning to move into separate collection i will help you make decision.

How should a REST URL schema look like for a tree hierarchy?

Let's assume that I have stores, shelves in a store, and products on a shelf. So in order to get a list of products on a shelf in a store, I'd use the following request:
GET http://server/stores/123/shelves/456/products
From here, how would I get an individual product? Should I use:
GET http://server/products/789
Or:
GET http://server/stores/123/shelves/456/products/789
The first method is more concise, since once you get a list of products, you don't really care which store it belongs to if you just want to view the details for a particular product. However, the second method is more logical, since you're viewing the products for a specific shelf in a specific store.
Likewise, what about a PUT/DELETE operation?
DELETE http://server/stores/123/shelves/456/products/789
Or:
DELETE http://server/products/789
What would be the correct way of designing a schema for a tree hierarchy like this?
P.S. If I'm misunderstanding something about the REST architecture, please provide examples on how I can make this better. There's way too many people who love to say "REST is not CRUD" and "REST is not RPC", then provide absolutely no clarifications or examples of good RESTful design.
I've noted 2 approaches to RESTful URI design: hierarchical & filtered
I feel hierarchical is overly verbose, has the potential for redundant endpoints (not DRY) and disguises in what resource's state you're really interested (after all, REST = representational state transfer).
I favor Simple URIs
Simple is elegant. I'd choose a URI structure like
GET http://server/products/789
because I am interested in the state of the product resource.
If I wanted all products that belonged to a specific shelf at a specific store, then I would do
GET http://server/products?store=123&shelf=456
If I wanted to create a product at a specific store on a specific shelf then I'd post
{
product: {
store: 123,
shelf: 456,
name: "test product"
}
}
via
POST http://server/products
Ultimately, it's tomayto, tomahto
REST doesn't require one over the other. However, in my own experience, it is more efficient to consume a RESTful API that maps single entities to single endpoints (eg: RestKit object mappings on iOS) instead of having an entity map to many different endpoints based on what parameters are passed.
About REST
As far as REST, it is not a protocol and has no RFC. It is tightly related to the HTTP/1.1 RFC as a way to implement its CRUD actions, but many software engineers will posit that REST does not depend on HTTP. I disagree and consider such as conjecture, because the original dissertation by UCI's Roy Fielding (http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm) explains the deep rooted connection of REST and HTTP/1.1. You may also enjoy Roy's opinion on the topic: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven.
The principles defined by REST can be applied to other protocols, but REST was built for the internet and HTTP is the protocol for the world wide web.
REST vs RPC
RPC is all about making calls to remote functions and is verb-centric.
REST is all about using the CRUD convention to act on data depending on how the CRUD operation applies to a given data type and is noun-centric.
You can accomplish the same things with REST or RPC, but REST follows DRY principles because for every URI you can perform 4 actions whereas RPC requires an endpoint for each action.
PS
Much of this is my opinion and based on my experiences, but I hope it sheds some light on how you could most efficiently design a RESTful URI schema. As always, your specific goals and needs will affect your choices, but simplicity is always a good target for which to aim.
Creating a product should just be a POST to
http://server/product
Updating a product should just be a PUT to
http://server/product/$id
Getting a product should just be a GET to
http://server/product/$id
Deleting a product should just be a DELETE to
http://server/product/$id
You should use the http methods that are there for you to get more functionality out of a simpler uri structure. If creating a product requires a passing in a store and shelf as a requirement, then those should get passed in the body of your POST (or PUT if you're changing shelves).
When someone does a GET to http://server/product/$id, they will get back some kind of xml/json response, right? What does that look like? The incoming data for a create or update should be POSTed or PUT the same way in the body of the request. That is how you pass in the store and shelf, not via the uri. The uri should be as simple as possible and just point to the resource (product), using the http verbs to differentiate functionality.
If you want to be able to get the contents of shelf 23, you do a GET to
http://server/shelf/23
When you do, you get back a json / xml / custom media type document that has the shelf data and a collection of product elements with links back to their product uri.
If you want to be able to move product 23 from one shelf to another, you do a PUT to
http://server/product/23
In the body of the PUT you have the product in the representation of your choice, but with the updated shelf.
It's a weird mode of thinking at first, because you're not dealing with functionality across the entire system, but instead focusing on the resources (product, shelf, store) and using the http verbs to expose them to the universe.
Don't design a REST api based on an URL structure. Here is how I think you should go about designing a REST api.
Trying to define a REST interface without discussing what links will be contained in what resources is like discussing an RPC interface and ignoring parameters and return values.
Since products may be in several stores or several shelves (categories?), I'd have each product have a unique number regardless of its position in the hierarchy. Then use the flat product number. That makes the API more stable when some products are for instance moved in your store.
In short, don't add unneeded redundancy to your API. To get a shelve list a store ID is enough, for a product list a shelve ID is enough... etc.
it seems like you are trying to build many different use cases, but everything is getting built into one super service. It would be better to break it out.
http://server/product_info/123123 or http://server/product_info?product=123123
http://server/product_inventory?store=123&shelf=345
then you can also support:
http://server/product_inventory?store=123
then PUT and DELETE makes sense for changing inventory or adding a new product.

Resources