1
votes

Let's say I have a database with customers and their orders. Each customer has general information like name, address, etc. Each order has information on items purchased, amount paid etc. The database is exposed through a RESTful API.

Presumably, a GET on a RESTful API URL like

/customers/101/orders/47/

would be expected to return the info (items purchased, amount paid, etc) for order 47 by customer 101.

I presume also that a GET on the following URL:

/customers/101/orders/

would be expected to return the information on all orders by customer 101.

However, what should a GET on the following URL return?

/customers/101/
  • Should it return all orders by customer 101?
  • Should it return just the name, address, etc of customer 101?
  • Should it return all orders by customer 101 and their name, address etc?

My question obviously assumes that there is a "right answer" or recommended best practice for what RESTful API URLs should return.

4

4 Answers

1
votes

I like this question. I think that this is very app specific. My thought would be just returning an anonymous object or JSON object of the capabilities specific to that customer along with their personal information (name and address).

That way i can check their authorized capabilities along with who they are and consume that information or validate that they can do what they want to do (bogus cheapo security layer maybe?)...

Good luck!

1
votes

It'll return customer info. This URL point to Customer resource, so It should return customer related data.

If you look at GMail REST API, similar request can return ids of orders, for example.

But not orders info.

1
votes

Assuming the number of orders per customer isn't huge, I would structure things as follows.

GET /customers/101
{
    "id": 101,
    "name": "John Smith",
    "orders": [
        "/orders/47",
        "/orders/52"
    ],
    ...
}

GET /orders/47
{
    "id": 47,
    "customer": "/customer/101",
    ...
}

Key points:

  • Don't nest resources in the URL
    • Nesting hinders your ability to restructure things later. What happens when you want to add multi-customer orders?
  • Link resources using their URIs
1
votes

The structure of the URL isn't what makes it RESTful; rather, you should provide an object which contains links to other data in an easily discoverable manner.

So, if the caller has so far done a GET to

/customers 

...you might expect that to return a list of "Customer" objects. Each Customer object would then contain links to appropriate objects, along with their URI. In your case, each Customer object might be along the lines of:

{
    "customer": {
        "id": 101,
        "self": {
            "url": "http://service.yourdomain.com/customers/101",
            "recommended_mediatype": "application/x.yourdomain.customer.v1"
        }
        "orders_list": {
            "url": "http://service.yourdomain.com/customers/101/orders",
            "recommended_mediatype": "application/x.yourdomain.order.v1"
        }
    }
}

This solves two problems for you:

  1. Whether to return the order, just the address, or both: The client can decide this by providing a different MediaType in the GET. The Customer object above recommends a MediaType of x.yourdomain.order.v1, but you might support a different representation type of (say) x.yourdomain.order-address.v1 which only contains the address data for the order. In this respect, you're providing for many different resource representations at the same URI endpoint.

  2. Not predetermining your URIs: By embedding the URI in the parent object (Customer) you aren't exposing the URI structure to your clients; making it more feasible to change in the future.

Hope that helps!