Reputation: 6852
Say I had a few business entities that I want to query from the Db, and do this within a Web API. Say, Customers and Orders. Each order can have exactly one customer.
Say I wanted to get
- all the orders for a given customer
- for a given order, return an object that contains some customer attributes, along with that customers 5 most recent order#'s
https://github.com/Microsoft/api-guidelines/blob/master/Guidelines.md#71-url-structure
Ive tended to use method names like these.
OrdersController:
- GetOrders
- GetordersforCustomer(int CustomerId)
- GetOrderWithCustomerInfo(int CustomerId)
CustomerController
- GetCustomer(int id)
- GetCustomerWithinZipcode
So using API controller methods like this does not follow the REST "guidelines" ive seen elsewhere, correct? If not, how could I restructure my controllers to accomodate the standard HTTP method names, especially when there are related entities?
For example, I need a call that returns an object that includes attributes from not just an order but the top 5 orders from the customer on the current order. I need a method that gets an order result, but also need a method that gets a different kind of order result - one with some attributes from a customer and/or maybe a few other entities.
example of what im talking about - using only http verbs but with related entities
https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#restful
But how do you deal with relations? If a relation can only exist within another resource, RESTful principles provide useful guidance. Let's look at this with an example. A ticket in Enchant consists of a number of messages. These messages can be logically mapped to the /tickets endpoint as follows:
GET /tickets/12/messages - Retrieves list of messages for ticket #12
GET /tickets/12/messages/5 - Retrieves message #5 for ticket #12
POST /tickets/12/messages - Creates a new message in ticket #12
PUT /tickets/12/messages/5 - Updates message #5 for ticket #12
PATCH /tickets/12/messages/5 - Partially updates message #5 for ticket #12
DELETE /tickets/12/messages/5 - Deletes message #5 for ticket #12
Upvotes: 0
Views: 150
Reputation: 247323
Question is broad and also opinion based.
That said, there is no need to restructure the controllers.
Research using attribute routing.
Reference Routing to controller actions in ASP.NET Core
Given the linked guidelines an example of potential routes could look like below suggestions.
[Route([controller])]
OrdersController:
//Matches GET orders
[HttpGet]
GetOrders()
//Matches GET customers/1234/orders
[HttpGet(~/customers/{customerId:int}/orders)]
GetOrdersForCustomer(int customerId)
Matches GET orders/1324/customer/5678
[HttpGet({orderId:int}/customer/{customerId:int})]
GetOrderWithCustomerInfo(int orderId, int customerId)
[Route([controller])]
CustomersController
//Matches GET customers
[HttpGet]
GetCustomers()
//Matches GET customers/1234
[HttpGet("{id:int}")]
GetCustomer(int id)
//Matches GET zipcodes/90210/customers
[HttpGet("~/zipcodes/{zipCode:int}/customers")]
GetCustomerWithinZipcode(int zipCode)
Upvotes: 0