I have a question regarding how to structure my controllers.
Let's assume I have a have a system that has stores and products and stores have products.
so the way to get stores is /api/stores/{id} and the way to get a product is /api/product/{id} or /api/stores/{id}/product/{id}.
How would you structure the Controllers? should I have a controller for products and controller for stores and every route that starts with stores in it should reside in StoresController otherwise in ProductsController?
This is from Microsoft: Api design guidance
In more complex systems, it can be tempting to provide URIs that enable a client to navigate through several levels of relationships, such as /customers/1/orders/99/products. However, this level of complexity can be difficult to maintain and is inflexible if the relationships between resources change in the future. Instead, try to keep URIs relatively simple. Once an application has a reference to a resource, it should be possible to use this reference to find items related to that resource. The preceding query can be replaced with the URI /customers/1/orders to find all the orders for customer 1, and then /orders/99/products to find the products in this order.
Related
Ok, my last question had no answers, so I've the doubt that I'm walking on the wrong way.
I'm developing some Web REST Api for a mobile application, and regarding REST best pratices I don't know how to face a many-to-many relationship.
I have two tables, Wallets and Cateories, between these tables there is a many to many relationship since a category may be associated to different wallets and a wallet may own different categories.
Actually this database is used by a non rest website:
when a user creates a new category, he choose from the list of his own wallets which wallets to connect it to, and with this single POST call the category is created and conneted to the wallets.
I don't think that replicating this behaviour is compliant to REST best pratices.
My first idea was to "expose" the connection between categories and wallets with this form:
http://localhost:8000/categories/77/wallets/4
but I had the problem I wrote on my previous question, and I don't think this is the right way.
Anyone has a valid method to manage a many-to-many realtionship according with REST best pratices?
Thanks in advance.
Namespacing wallets by a category is fine, as in /categories/77/wallets/4. You can also consider a more concise scheme like /categories/77/4 or /wallets/77/4 if there are only wallets in a category.
However, you don't have to namespace. Your wallets presumably have their own IDs, so you could also just expose them as /wallets/4.
Is it worth the effort? I think it can be a good practice if your URLs are also on a public website (in which case you would probably want to support slug IDs as well, e.g. /categories/luxury/wallets/acme). If not, you should be aware it will be a little more configuration work on the server-side and a little more work for clients (clients will have to be aware of 2 IDs instead of 1).
I want my ZF2 Application to import data from many different REST or SOAP Services, which may use different authentication types and so on.
Now I'm basically looking for a structure / architecture how to implement this, maybe some design patterns or ready to use modules if they exist.
Every information could help. I'm also thankful for API docs or tutorials that you provide.
But my main question is: How should be the structure for this kind of "importer"
My Application:
Based on Zend Skeleton Application
Using Doctrine 2
Trying to use all ZF2 Best Practices I can find
Consists of many modules, entities and complex associations in some cases
Entities that I want to import are already working (crud operations, validation, ...)
Apis that I want to use:
Usually E-Commerce stuff, like products, orders, stock keeping
Magento Api (Thinking of Rest)
Shopware and other important Webshops
Ebay Stores
Amazon (I think is going to be the hardest one)
Must have functionality:
I want the api URLs and authentication data to be configurable in my app with doctrine entities
The "Api" Entity should be associated to my "Shop" Entity. Orders or Products that I import or create directly in my App are also associated to my Shop entities. So every Shop/Ebay-Store/Amazon-Store is a "Shop" in my Application. This is already the part I've done.
For example product import should be done directly from my app frontend, I'm thinking of retrieving the api data first and then import them incremtally / step for step
I don't want fat controllers that transform the data into doctrine entities and save them one by one. This way complex associations would become very hard to maintain.
Need a good approach for data transformation and hydration to doctrine entities. Because the data I retrieve from api will usually not have the same structure as my entities. Maybe an attribute that's a property of the "Product" entity in foreign app is excluded into an associated entity in my own application.
Many modules in my application will have entities that should be importable from these apis, so I need a central component that does the job
How would be the best approach for this? I'm not asking for a complete solution, but ideas that fit these requirements.
The Zend HTTP client and its relatives (like Zend OAuth) provides most of the functionality that you need to implement fetching the data from the services.
You can then persist the response in any number of ways, but a schema-less database like Mongo DB makes saving dynamic data much easier. If you are stuck using a relational DB like MySQL then you can either setup an EAV database, or use dynamically generated tables.
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 a rails programmer who is on to his 3rd project now (new of course).I am looking for an answer to a general question about Restful architecture. I am sure i am doing something that has a good established answer already.
In restful approach we expose resources but some times this approach feels a little Non user friendly. For example i can expose a product via a show method and then i have another resource called sales that i can expose via product/:id/sales show template to show all sales for a product. But i am taking the user through an extra click here. The ideal will be to show product and all its associated sales on one page itself. But that is a violation of the Restful rule.
I just wanted to ask that are these rules generally broken to make the site user friendly? Being a new comer i dont want to adopt ways that are non ideal so i thought i should ask this question.
Thanks in advance.
Adding in the sales for a particular product would not be breaking any constraints from the RESTful architecture. You have the product ID in the HTTP request so you can just also get the sales for that product. Your separation of concerns should not be affected and you don't need to store a state to get this information. Just extend the model that you return with the view.
It seems like you are more concerned with straying from the convention over configuration that Rails promotes. This extension means that your model will not correlate with only one table in your database, but that is fine. The conventions are meant to reduce the configuration work that you need to do, not restrict your functionality.