Search code examples
apiasp.net-web-apiapi-design

Add a single or multiple API endpoints when accepting POST request?


I have planned to build a multiple service endpoints such as these in order to update multiple entity items.

/api/order(orderInfo) [httppost]
/api/orderChangeCurrency(orderCurrency) [httppost]
/api/orderChangeClientName(orderClientName) [httppost]

public class orderInfo()
{
public int orderID {get;set;}
public int orderType {get;set;}
}

public class orderCurrency()
{
public int orderID {get;set;}
public int currencyID {get;set;}
}

public class orderClientName()
{
public int orderID {get;set;}
public string firstName{get;set;}
public stringlastName{get;set;}
}

But it crossed my mind to have a single endpoint instead that would do all of it

/api/order(orderExtendedInfo) [httppost]

public class orderExtendedInfo()
{
public int orderID {get;set;}
public orderInfo? OrderInfo{get;set;}
public orderCurrency? OrderCurrency{get;set;}
public orderClientName? OrderClientName{get;set;}
}

In this case I would have a business logic that would update entities based on the information provided (null values or not).

Is there a recommended practice or a rule for API endpoints in this specific case?


Solution

  • Well, that's quite a broad question and might be more suitable on http://programmers.stackexchange.com but I'll drop some considerations anyway.

    First of all, your API design should be geared towards the users of your API. If your API will be a public facing API you might consider REST. It's is a widely used (and debated) architectural style and lots of programmers are used to this style. A very useful list of recommendations on designing a RESTful API can be found here

    Second, you should consider the consumability of your API. To take your design as an example: would it be logical for a consumer to update the entities one by one or would it be more logical to update one or more or even all entities at once?

    Third, you'll have to take database transactions into account. When all entities should be updated in one atomic operation then you cannot provide three endpoints.

    Personally, I'm quite fond of REST so I'll happily provide an example for your use case.

    Example

    First let me introduce a new entity:

    public class OrderLine 
    {
        public int Id {get;set;}
        public int OrderId {get;set;}
        public int ProductId {get;set;}
        public int Quantity {get;set;}
        public decimal Price {get;set;}
    }
    

    Endpoints

    POST /api/orders                  # creates a new order 
    GET  /api/orders                  # gets all orders
    GET  /api/orders/1                # gets order 1
    POST /api/orders/1/orderlines     # creates a new order line for order 1.
    GET  /api/orders/1/orderlines/1   # gets order line 1 of order 1
    GET  /api/orderlines/{id}         # gets order line 1
    

    If you need to update multiple entities in a single operation you could do it like this:

    Create a model for the update:

    public class EditOrder
    {
        public int orderID {get;set;}
        public int orderType {get;set;}
        public int currencyID {get;set;}
        public string firstName{get;set;}
        public string lastName{get;set;}
    }
    

    And then use this endpoint

    PUT  /api/orders/1 
    

    And this method

    public IHttpActionResult Put(int id, EditOrder editOrder)
    {
        // retrieve current Order, OrderCurrency and OrderClient
        // update the entities 
        // save entities
    }