Proper REST URL format - rest

My REST API format:
http://myserver.com/rest/messages - get all messages
http://myserver.com/rest/messages/5 - get message with id=5
How should the URL look when I want to get all messages owned by a user with id=1?
http://myserver.com/rest/messages/user/1
OR
http://myserver.com/rest/usermessages/1 (no such entity UserMessage exists in the system)

This sounds like a filter/search for messages. This is usually done by query parameters:
GET http://myserver.com/rest/messages?ownedBy=1
Since /messages is a collection resource from which you want a subcollection, you filter it.

Related

Determine the proper REST API method

I have the following functionalities in my API:
Getting a user by their name
Getting a user by their ID
Getting a user, or if it doesn't exist create one
Getting multiple users by their ID
Currently I'm handling the two first functionalities with a GET request, and the third with a POST request. I could use a GET request for getting multiple users, but sending potentially hundreds of IDs through a query parameter seems like the wrong approach, as I would get a very long URL. I could also use a POST request to send the long list of IDs through its body, but I doubt a POST request is meant for this purpose.
What method would be appropriate to use for the last one?
I see 2 possible ways here:
Get all users and do your filtering post response.
Get a range of IDs, which resumes to only 2 parameters, the lower and the upper limits of the interval. (If this satisfy your needs)
Behaving the way you described and avoiding long URLs in the same time will not work together.

How do I keep a nonexistent work ID from breaking an API query?

I am querying the Azure DevOps API to return data for several work items at a time. The basic query is:
https://dev.azure.com/<organization>/_apis/wit/workitems/?ids=1234,2345,3456&api-version=6.0
But if one of those is not a valid work item ID, it returns something like this within the JSON response:
"message":"TF401232: Work item 3456 does not exist, or you do not have permissions to read it."
To me it seems like a better response would be the normal multi-ID JSON object with that message as one of many work item ID responses, instead of letting an invalid response break the entire query. Is there any way to do that? I haven't found any argument that seems to accomplish that, but I could easily have missed it. Thank you.
You can use the errorPolicy query flag in the api url. Set errorPolicy to Omit. See below:
https://dev.azure.com/<organization>/_apis/wit/workitems/?ids=1234,2345,3456&errorPolicy=Omit&api-version=6.0
When you useerrorPolicy=Omit query flag. The nonexistent work item id will not break the API call. It will be omitted in the response instead.
See here for more URI Parameters.

Is it a good practice to use 'createModel' in REST?

I'm looking for a best way for implementing an endpoint of REST-full application that will be responsible for creating a new library orders. Let's assume that I have the following resources.
If I want to get all books of a particular author I can use the next endpoint:
HTTP GET
api/books/author/123
If I want to fetch all orders of a particular book I can use the endpoint provided below:
HTTP GET
api/books/456/orders
My question is what will be the most suitable URL and a request model for an endpoint that will create orders?
From my perspective it can be
HTTP POST
api/books/456/orders
And one more question. Is it a good practice in REST to use request models like CreateOrder? If I want to create a REST-full web application can I use the following request model:
class CreateOrder
{
AuthorId: number;
BookId: number;
ClientId: number;
}
Sometimes it makes me confused. Should request models look like our resources or not?
Let's assume that I have the following resources.
Your "resources" look suspiciously like "tables". Resources are closer to (logical) documents about information.
what will be the most suitable URL and a request model for an endpoint that will create orders
For the most part, it doesn't matter what URL you use to create orders. In a hypermedia application (think HTML), I'm going to submit a "form", and the meta data associated with that form are going to describe for the client how to compose a request from the form data.
So the human, or the code, that is manipulating the form doesn't need to know anything about the URL (when is the last time that you looked to see where Google was actually sending your search?)
As far as general purpose web components are concerned, the URL/URI is just an opaque identifier - they don't care what the spelling means.
A thing they do care about is whether the spelling is the same as something that they have cached. One of the consequences of a successful POST /x message is that the cached representation(s) of /x are invalidated.
So if you like, you can think about which cached document should be refreshed when an order is created, and send the request to the identifier for that document.
Should request models look like our resources or not?
It's not necessary. Again, think about the web -- what would the representation of create order look like if you were POSTing form data?
clientId=1&bookId=2
or maybe
bookId=2&copies=3
If the "who is creating an order" is answered using the authorization headers.
In our HTTP requests and responses, we are fundamentally sending message representations - sequences of bytes that conform to some schema. There's no particular reason that those sequences of bytes must, or must not, be the same as those we use elsewhere in the implementation.
Your end-point does not need to always start with /books. You can introduce another end-point /orders for creating or getting orders. So , to create an order , you can :
HTTP POST
api/orders
And does the 'request model' that you mean is the HTTP request body structure ? If yes, it does not need to be 100% match with your back-end persisted/domain model. Just include enough parameters that the server needs to know in order to create an order. (e.g. Include bookId rather than the whole book object etc.)
BTW , to get all books for a particular author , it is more common to use query parameter such as :
HTTP GET
api/books?authorId=123
What you are doing is not REST, it is CRUD over HTTP. REST does not care about your URI structures and resources are very far from database tables. If CRUD is all you need, then download a CRUD generator library https://github.com/search?q=crud+generator&type=Repositories, which will generate all the upper and you won't need to write it manually.

Add subcategories in a filtered API Restful resource

I'll give an example as the title might sound a bit confusing.
How to build a resource path for something like that:
GET /courses/?language=english&active=true/units
I want to filter the courses (not using an id as usually) and then get the units of this result. How would you do that? I guess using question marks between the path is not allowed.
That would depend a little on your DB schema of what is a "course" and a "unit". The whole point on using the RESTful way is to always build requests and urls resource-specific.
But let's say that one course has X units on it. Here's what i would do to make a RESTful path to that request:
Due to the path problem of filtering courses AND using the /unit suffix, it can be done by adding another query parameter that specifies what fields the request is supposed to return. Something like this:
GET /courses?language=english&active=true&fields=units
That would filter the courses, and then return only the 'units' field on the response. As i said, depending on your DB and models, if the units are not stored inside the courses, it would be a bad practice to get them by requesting a /courses path. In that case, first request the courses that match the desired filter, and then make another request to the /units context sending i.e the courses ID's as query parameters.

What could be a valid URI template for REST API handling a GET HTTP request with multiple parameters?

I am developing a RESTful API that handle a GET request needing 2 parameters.
I try to explain better the use case: This API will return the latest price of a specific commodity (the commodity_id is one parameter) in a specific market (the market_id is the second parameter).
So what can be a valid URI template for this pourpose?
Something like this:
/latest_commodity_price/{commodity_id}/{market_id}
or something like this:
/latest_commodity_price/{commodity_id}?market_id={market_id}
or something like:
/latest_commodity_price?commodity_id={commodity_id}&market_id={market_id}
Or what else?
In RESTful ways your approach starts at the wrong position. REST means you are querying resources. So the URI should start with the resource you are querying your API for.
/commodity/{commondity_id}
Then you want to have a list of prices for a market. This sound like you query your API to retrieve a list of prices for the commodity:
/commodity/{commondity_id}/prices
Finally you are filtering the list of prices. I recommend doing filtering with the query parameters:
/commodity/{commondity_id}/prices?market_id={market_id}&latestPrice=1