Search code examples
restmany-to-manyapi-design

Modelling URI to demonstrate many to many relationship between 2 API resources


A credit card account (Account) can belong to multiple customers and One customer (Customer) can own multiple credit card accounts. I need to design REST API(s) which can return all accounts owned by a customer. The account number is coming from a manual input by an end user like a service rep into a freeform text box. Following is a constraint though

  1. End consumers/developers know only account number & have no knowledge of customer id (unique identifier of a customer) upfront so to retrieve a list of accounts belonging to a customer -

    1.1 find the customer owning the account in question

    1.2 then find all the accounts owned by a customer.

I can think of couple of options but feel either they will make interaction chattier or may not be restful.

Only GET scenario has been discussed in below options

Option 1

Ideal way to interact with two separate resources but makes interaction very chatty and will put undue load on the system. Two calls everytime to know all accounts owned by a customer. So 20 Million calls/day in SOAP/RPC will become 40 million calls in REST.

/accounts/{account_nbr}/customers --> returns a list of customers for a specific account
/customers/{customer_id}/accounts --> returns a list of accounts for a customer

Option 2

I don't think this will be restful because query parameter is supposed to be used for identifying a resource in a non-hiearchical data

/customers/accounts?account_nbr = XXXX

Option 3

This option indicates that a list of accounts linked to account_nbr is being returned which is not right because list of accounts are linked to a customer

/accounts/{account_nbr}/linked_accounts

Option 4

Term the relationship between customer and an account as a new type of resource. Its trying to indicate get a list of customer to account relationships and identify specific instance where an account in customer_account_relationships has a value of XXXX. /customer_account_relationships?account_nbr=XXXX or

Which of the above option, if any, is close to being restful representation? Is there any other way to design this interface?

EDIT

Expected response

{
  "customerName" : "Bob",
  "customerId" : 1234,
  "listOfAccounts": [
          {
             "accountNbr" : "abcd"
             "accountType": "creditcard"
          },
          {
             "accountNbr" : "qrst"
             "accountType": "creditcard"
          }
     ]
 }                             

Solution

  • You correctly rejected the first three options. I see two reasonable choices for you. One is to go with option 4:

    GET /customer-summaries?account-number=<account-number>
    

    The other is to just make /accounts top-level and do essentially the same thing:

    GET /accounts?same-owner-as-account=<account-number>
    

    In the former case, you'd get an instance of your resource above. In the second, you'd just get a list of accounts, each of which presumably has a link to the account owner. It's up to you as to which better suits your use case.

    Note that option 4 may return multiple records if there are multiple owners for the same account. That's a common situation for married couples.