REST Get items not in collection - rest

Introduction
Let's say I have a rest service which returns items:
GET /items
GET /items/7
POST /items
etc.
We also have groups of items:
GET /groups
GET /groups/16
POST /groups
etc.
And we can then get the items in a specific group:
/items?groupid=16
This is all pretty straight forward.
Question
Now that we have a way to get items in a specific group, should we also supply a way to get items that are NOT in a specific group? Why? Because if a client wants to add items to a group, it has to know which items aren't added yet.
I see two options:
We supply some way to query the data
Don't do anything, let the client handle it.
Ad 1.
We can supply a way to query/search the data like this:
/items?groupid=!16
or
/items?q=groupid<>16
I have the feeling this leads to a never ending stream of feature requests for search queries.
Ad 2.
The client can first get all items. Next the client can get all items in group 16. Doing a diff on these two collections gives the items not in group 16.
This way the client has to do a little more coding, and work with collections, keep them in memory etc. On the other hand it doesn't need to learn a specific query syntax.
Are there any best practicies on this topic?

First, I'd use a different URL to get the items in a group:
GET /groups/16/items
This would return the collection resource of all items that are in group 16. To add an item to a group,
POST /groups/16/items
could be used.
Adding an item to a group will have the same result, regardless of the item already being in the group or not. In both cases the client only cares about the result: he wants the item to be in the group. If it already was, fine, if not, it is now.
So I don't see any usecase for getting items that are not in a group.

Perhaps allowing the client to POST the new item to the desired group could be the way to go.
During the validation you would need anyway, you could either accept the not-pre-existing item or reject it because it is already there.
Building on the URLs of #Tichodroma, you could perhaps have:
GET /groups/16/non-items

Related

REST endpoint, get nested resource with unique ID

I have the following dilemma while designing some endpoints. We have items that always belong to orders so it felt natural to got with the following endpoint for creation of an item:
POST /orders/{orderid}/items
However this item has a unique ID, meaning we can fetch it without knowing the parent order. This means that the following is unnecessarily elaborate:
GET /orders/{orderid}/items/{itemid}
At the same time it feels inconsistent to use it without the orderid because it was created with, like:
GET /orders/items/{itemid}
And also, one would get all items belonging to an order using the following for example:
GET /orders/{orderid}/items
One could even go as far as to say that, because we don't need to know the parent we can simplify it to:
GET /items/{itemid}
I've read quite a few post on the subject so far, but have not found any suggestions for this specific case.
So what is the way to go here? Is there even a specific way to go, a best practice?

REST API best practices: ignoring filter when empty

In the scenario of a users API (/api/users) with a property of team_id, I want to set up an endpoint that allows me to get users with specific team IDs, i.e. /api/users?team_ids=1&team_ids=2&team_ids=3.
My question is, what if I want to ignore this filter?
For instance, if there's a multiselect dropdown in the UI and the user de-selects all team_ids, the expected result would be nothing as they have selected zero teams, and all users are in a team. From an API perspective however, I think it would be reasonable to expect that /api/users would return all users.
You can simply make that parameter required then, so if it doesn't exist the response is an empty array. Or you can limit the amount of users returned

Can particular item be closed REST API

I want to implement a REST endpoint to figure out whether a particular item can be closed. How can I do it properly from the point of view of REST design?
/items/canbeclosed - sounds ugly
maybe something like
/items/status but I have already status endpoint used for another purpose
How can I do it properly from the point of view of REST design?
REST doesn't care what spelling you use for your URI.
It might help to think about what's true of the items now, rather than thinking about which actions are possible. For instance, if the items "can be closed" because they are "completed", then /items?completed or /items/completed or even '/completedItems' might be reasonable spellings.
Alternatively, perhaps these are tasks, sitting in a task queue, with different queues set up for your different stages. So something like /stages/closeItem/tasks might be the right thing.
Your touchstone, as with all things REST, is to imagine your API as a web site. If you had to navigate to a web page to access this information, what would the identifier of the web page be? and there you go.
You have several different possibilities depending on what you want to do specifically.
For getting whether a particular item can be closed, retrieve the item and have a field that answers this question:
GET /items/{itemNumber}
{
"canBeClosed": true,
...
}
You could also use a subresource for that particular field:
GET /items/{itemNumber}/can-be-closed
true
This would also be "resty" but it's only helpful in some edge cases. You wouldn't want to make a call over the network for every little piece of information. This would result in bad performance.
Note that the solutions above point to a single resource identified by its ID. Have a look at restapitutorial.com for the difference between collection resources and item resources.
Maybe you want to get a list of the items which are closable:
GET /items?closable=true
In this case I'd like using a matrix param more:
GET /items;closable=true
Matrix params are much like query params except that they are bound to a particular path element rather than to the end result. So you can have something like this:
GET /customers;country=Germany/orders
which would return the orders of customers living in Germany. This is not possible with query params as they are always added to the end. So in my eyes they are better for paging and sorting while matrix params are better for filtering.

RESTful URI to select "My" items

I want to expose my Item resource in these ways:
GET /Item (to show all Items)
GET /Item/401 (to show only the Item with key value 401)
So far so good. Now to request only the Items that belong to Me, I can think of these possible URIs constructions:
GET /Item/Mine
GET /MyItem
GET /Item/owner=42 (where my ID is 42)
I don't like the last one because it simplifies my client programming to rely on existing authentication to figure out "My" ID. I happen to be coding on ASP.NET WebAPI, but I'm really asking about the principle and design, not the implementation.
My question: Which of the three ways to represent "My" Items is most consistent with the RESTful design concept? Is it even legitimate to ask for "My" Items as such?
If users should not be able to see items that aren't "theirs", then this is an authorization issue. Just use GET /Item, and have your authorization module strip out the items that aren't theirs.
If users can see all items, and you just want to grab the items that belong to a particular user, then you should be parameterizing the call to GET /Item. Something like GET /Item/?owner=42. In this case, the user isn't limited to asking for their items .. they can ask for the items of any owner. That buys them flexibility without costing you anything.
If you have a /User resource, you could also add an endpoint /User/{id}/Item, which
returns the same collection as /Item/?owner=
And this isn't germane, but I find that plural collections (/Items, /Users) read a lot better than singulars. YMMV.
I would use GET /Items to get all itmes.
And GET /Items?owner=42.
GET /Item/Mine is not consistent since it contradicts your way of identifying the resource ie, GET /Item/401.
GET /MyItem seems seems unnecessary since the resources you are looking for can be retrieved using the other REST url paths.

Multiple tags / folders in Google Reader

I want to be able to grab data from multiple tags / folders in a users Google Reader.
I know how to do one http://www.google.com/reader/atom/user/-/label/SOMELABEL but how would you do two or three or ten?
Doesn't look like you can get multiple tags/folders in one request. If it's feasible you should iterate over the different tags/folders and aggregate them in your application.
[edit]
Since it looks like you have a large list of tags/folders you need to query, an alternative is to get the full list of entries, then sort out the ones the user wants. It looks like each entry has a category element that will tell you what tag is associated with it. This might be feasible in your case.
(Source: http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI)
(Source: http://www.google.com/reader/atom/user/-/state/com.google/starred)
I think you cannot get aggregated data as you hope to be able to. If you think about it, even Google lets you browse folders or tags one at a time, and do not aggregate a sub-set of them.
You can choose to have a list of all the items (for each one of their available statuses) or a list of a particular tag/folder.
You could do it in 2 requests. First you need to perform a GET request to http://www.google.com/reader/stream/items/ids. It supports several parameters like
s (required parameter; stream id to fetch; may be defined more than one time),
n (required; number of items to fetch)
r for ranking (optional)
and others (see more under /ids section)
And then you should perform a POST request (this is because there could be a lot of ids, and therefore the request could be cut off) to http://www.google.com/reader/api/0/stream/items/contents. The required parameter is i which holds the feed item identifier (could be defined more than once).
This should return data from several feeds (as returned for me).