In a big system, where there are an api for lots of resources, I want split documentation in some configured manner.
Like if they were different apis.
So in main page of web api I have a list of configured 'resources'.
Let's say:
Managing contacts [Here i want to expose the 'contact' resource, the 'address' resource, etc.
Managing orders [product resource, order resource, delivery resource, balance resource, etc]
Managing products [product resource, category resource, etc]
So it's easier for api consumers to understand based on the task to accomplish which methods should been taken care of.
Also, as you can see, different sections use same resources, that means if I change something on the Product resource, both documentations should (ideally) be automatically updated, including versioning info, etc.
EDIT:
public ActionResult Index()
{
ViewBag.DocumentationProvider = Configuration.Services.GetDocumentationProvider();
return View(Configuration.Services.GetApiExplorer().ApiDescriptions);
}
this is my index action on helpcontroller, not sure what you mean.
Have you looked at HelpController under Areas\HelpPage\Controllers? If you notice the Index action of this controller displays information about all controllers.
If each of your resource is represented by a controller, you should be able to filter the ApiDescription to only show only the resources that you like to.
Related
We have a recipe in our mobile application, this recipe has a details screen and the details screen has a lot of information, for example:
Rating
Related recipes
Ingredients
Recipe info
Nutritional info
So is that right to return all this info in the same endpoint or create multiple endpoints for each section?
One endpoint example:
GET: https://www.example.com/api/v1/{recipeId}
Multiple endpoints example:
GET: https://www.example.com/api/v1/{recipeId}/info // this API will return all info including the ingredients
GET: https://www.example.com/api/v1/{recipeId}/rating
GET: https://www.example.com/api/v1/{recipeId}/related
GET: https://www.example.com/api/v1/{recipeId}/nutritional
It depends.
If a consumer of your API is say a web page where you want to display all the information at the same time in one click, you can just bring all information together and display in one go rather than calling APIs one by one and then aggregating, however if there is possibility that individual endpoints are also required to be called separately, then you can expose multiple endpoints.
Also,your resource uri should be like this :
/api/v1/recipes/{recipeId}
In this case, you can create a single API endpoint. And, can expose a query parameter which shows which are the fields user (rest client, web) is interested in.
/api/v1/recipes/{recipeId}/?fields=all
/api/v1/recipes/{recipeId}/?fields=info,rating,related
/api/v1/recipes/{recipeId}/?fields=info
In this way, you will be saved from the headache of writing multiple endpoints for a single serving type.
Also, the schema of output message or JSON will be the same.
Maybe in future, you want to add another field to your response. You just need to add another filter name. Your client (web/rest) doesn't need to use a new API for that. Just pass the new filter and done.
We have an app which is exposing a RESTful API to a UI for purchasing an item. I have a question regarding API design. Lets say the following action should be taken in order
Item to be chosen for purchase
Next give the address to be delivered to
My question is: should we design a single API which gets both data perform both? Or should we design two API calls - one that creates a purchase record and second that update the address to be delivered to?
The recommended SOA approach is to choose coarse-grained services, which would seem to argue the minimum amount of API calls.
However, from a business point of view, item selection and purchase and item delivery are two very different concerns that should be separate components in your architecture. For item selection, you need to consider things like inventory and pricing. For delivery address, you need to consider user address lists, address validation, shipping, and taxation.
Those two components are not likely to interact much except maybe some external association between an item id and address id. For this reason, I'd recommend two API calls. Functionally, this would also allow your API users do things like update the delivery address without re-purchasing an item, send the bill to one address and the item to another address, etc.
As you state that you design a RESTful API you usually start by designing resources instead of the intended calls. Later on, resource representations can be chosen that include other resources for optimised HTTP request counts.
You might want to choose to proceed the following way:
Model the item list resource (GET - lists all items, POST - allows item creation) /items/
Model the address list resource /addresses/
Model the item instance resource /items/item/resourceId
Model the address instance resource /addresses/address/resourceId
Now all of your resources are available you can think about usage patterns. All your resources are generically available and can be mashed up.
Possible approaches to answer your questions would be:
Extend the item instance resource with the needed address details (coarse grained as lreeder stated)
Model a resource /deliverydetails/ as list and instance resource containing item(s) and address, make the deliverydetails to be queried by item id or whatever your use case fits best
Hope that helps!
Btw. you are automatically following SOA approaches with a Resource Oriented Design. Interfaces will be naturally fitting your business requirements and generic enough to support more advanced use cases.
Here is a good example
I'm trying to wrap my head around how to design a RESTful API for creating object graphs. For example, think of an eCommerce API, where resources have the following relationships:
Order (the main object)
Has-many Addresses
Has-many Order Line items (what does the order consist of)
Has-many Payments
Has-many Contact Info
The Order resource usually makes sense along with it's associations. In isolation, it's just a dumb container with no business significance. However, each of the associated objects has a life of it's own and may need to be manipulated independently, eg. editing the shipping address of an order, changing the contact info against an order, removing a line-item from an order after it has been placed, etc.
There are two options for designing the API:
The Order API endpoint intelligently creates itself AND its associated resources by processing "nested resource" in the content sent to POST /orders
The Order resource only creates itself and the client has to make follow-up POST requests to newly created endpoints, like POST /orders/123/addresses, PUT /orders/123/line-items/987, etc.
While the second option is simpler to implement at the server-side, it makes the client do extra work for 80% of the use-cases.
The first option has the following open questions:
How does one communicate the URL for the newly created resource? The Location header can communicate only one URL, however the server would've potentially created multiple resources.
How does one deal with errors? What if one of the associons has an error? Do we reject the entire object graph? How is that error communicated to the client?
What's the RESTful + pragmatic way of dealing with this?
How I handle this is the first way. You should not assume that a client will make all the requests it needs to. Create all the entities on the one request.
Depending on your use case you may also want to enforce an 'all-or-nothing' approach in creating the entities; ie, if something falls, everything rolls back. You can do this by using a transaction on your database (which you also can't do if everything is done through separate requests). Determining if this is the behavior you want is very specific to your situation. For instance, if you are creating an order statement you may which to employ this (you dont want to create an order that's missing items), however if you are uploading photos it may be fine.
For returning the links to the client, I always return a JSON object. You could easily populate this object with links to each of the resources created. This way the client can determine how to behave after a successful post.
Both options can be implemented RESTful. You ask:
How does one communicate the URL for the newly created resource? The Location header can communicate only one URL, however the server would've potentially created multiple resources.
This would be done the same way you communicate linkss to other Resources in the GET case. Use link elements or what ever your method is to embed the URL of a Resource into a Representation.
I am curious as to how a CRUD REST API would implement the idea of a tweets resource. Of course, an application such as Twitter has the notion of tweet objects, but these are needed by the application in various ways ("collections").
Twitter would need an endpoint for user timeline (tweets published by a certain user) and also for the home timeline (the timeline of tweets from people a user is following). I imagine, in a CRUD API, user timeline would be located at a URI such as: tweets?filter={username:"Bob"}
However, I'm not quite sure how a CRUD API design would implement the home timeline collection of tweets. Furthermore, collections such as favourites for a user — are these treated as separate resources altogether, or should they somehow be attached to the tweets resource?
Furthermore, Twitter have not used the CRUD design for their API. Maybe there is a good reason for this?
The good thing about resource design is that it doesn't really matter, as long as it makes (some) sense. Obviously some nuances are in place, but let's get to the point. Business models don't (have to) map 1:1 to resources, this is probably why you don't find such relation in the Twitter API.
Some assumptions: Timelines are pre-defined and their behaviour isn't influenceable, other by creating new tweets. Favorites are (references to) tweets. Favorites are influenceable.
A favorite collection resource, could be something like:
/user/bob/favorites
Your "CRUD" operations could be something like:
[POST] /user/bob/favorite { "tweet_id": "343fe4a" } -- Add a new favorite
[GET] /user/bob/favorite -- All favorites, for the user Bob
[DELETE] /user/bob/favorite/343fe4a -- Delete tweet 343fe4a as being favorite
Normally it's best to avoid multiple variables in a single resource, as this introduces a certain complexity that isn't needed. In this example, however, a favorite doesn't have it's own identifier. It instead re-uses the identifier from a tweet and it's also tightly-coupled with a user.
If a favorite does have it's own identifier, I would go about creating a resource like: /favorite/ef213e13f this could return meta-data or act as an alias (redirect) to a tweet for a HTTP GET method or a resource to "un-favorite" something (DELETE method).
This statement probably makes more sense if we don't talk about tweets, but instead about a blog with articles and comments:
/blog/article/42 -- representing an article
/blog/article/42/comments -- representing a collection to all comments for this article
/blog/comment/44571 -- representing a single comment
Depending on what you want, a couple of examples for timelines could be resources like:
/user/bob/timeline/home
/user/bob/timeline?type=home
/timeline/home?user=bob
As I mentioned earlier, it's best to avoid using multiple variables in a resource. I would probably pick option 3. The reasons being, besides the complexity of having too many variables, is that such a resource probably isn't worth caching (client-side) and no CUD actions may be done on it. Since it's most likely an aggregate resource for different entities.
A couple of closing words:
Design resources first and only then come up with a matching URL
Don't design resources 1:1 to (business-)models
Don't over think the situation from the start. Implement something and tinker with it to see possible problems in the future. Once you're happy, put it in production.
Suggestions for further reading:
HAL - http://stateless.co/hal_specification.html
Hypermedia - http://en.wikipedia.org/wiki/Hypermedia
RMM - http://martinfowler.com/articles/richardsonMaturityModel.html
Roy Fielding's blog - http://roy.gbiv.com/untangled/tag/rest
Say, for example, I had a REST api url design with "Customer" as a resource.
Now, I want to be able to list all customers, find a specific customer by ID or Email address
Also, I want to be able to add a new customer...
Are these example URIs right?
Or should I be doing it another way..?
/customer/1234
get customer with id 1234
/customer/email/john#smith.com
get customer with email address
[POST]
/customer/
creates a new customer
/customers/
list all customers (notice pluralization)
In my experience RESTful APIs use a single resource path that is plural. The idea is that you have customers and when you want to interact with a customer you are interacting with the customers resource in general.
GET /customers to get a list of customers.
POST /customers to create a new customer.
GET /customers/:id to get a specific customer with a unique id. (Generally not an attribute of a customer like email)
GET /customers?email=bob#example.com to get customers with a specific attribute value.
Apigee has a blog post that covers pluralization that you might want to read.
If I was designing this API I would start with a generic hypermedia type like HAL and design a root representation that provides me access to the various scenarios you describe using links and uri templates.
e.g
GET /api
=>
<resource>
<link rel="urn:mycompany:customer" href=".../{id}"/>
<link rel="urn:mycompany:customers" href="..."/>
<link rel="urn:mycompany:customersearch" href="...{?email}"/>
</resource>
I have not filled in the actual URLs because from the perspective of the consumer of the API it really does not matter how those URLs are structured. Do whatever is easiest in you server framework. Don't worry if you get it wrong, you can change it later and your clients won't break because they should discover the URL from the root representation.
It is fairly common to assume that POSTing a customer to a collection of customers will create a new Customer, so you could just require your consumers to use that link. Or if you wish to be more explicit you could define a new link relation that provides a URL for creating Customers.
This is how I would do it:
/customer/1234
customer/john#smith.com
or (if email not guaranteed to be unique)
customers/search?email=john#smith.com
[POST]
/customers/ (notice the plural, same as below)
[GET]
/customers/
Cheers,
Ferenc
Why not be robust and enable both /customer and /customers?
GET /customer/1234 or /customers/1234 retrieves the same resource.
GET on /customer or /customers gives a list of all customers.
POST to /customer or /customers creates a new customer.