GaryR
GaryR

Reputation: 11

REST API one-to-many resource relationships best practice

Let's say I have one-to-many relationship here:
Each customer has many credit cards.

And the API endpoints for credit card:
GET /customers/{customer_id}/cards/{card_id}
GET /customers/{customer_id}/cards
POST /customers/{customer_id}/cards
PATCH /customers/{customer_id}/cards/{card_id}
DELETE /customers/{customer_id}/cards/{card_id}

5 methods for card-related operations:
1. Get a card of a customer
2. Get all cards of a customer
3. Create a card for a customer
4. Update 'a card' details of a customer
5. Delete a card of a customer

My API architecture layering uses controller -> service -> repository.
There are:
CustomersController, CustomersService, CustomersRepository, CardsService, CardsRepository.

My question is, where should I put each method for card-related operations and how should the relation between the controller & service & repository layer be like?

Currently I think of it this way:
CustomersController has a CustomersService and a CardsService. CardsService has a CustomersRepository and CardsRepository (injected via constructor as usual). All the 5 methods above reside in CardsService. The purpose of CustomersRepository in CardsService is to retrieve stripe customer id from my DB so I can perform the same operations on Stripe too.

Is this approach correct according to the best practice? Or should I put the 5 methods in CustomersService instead thus not using CardsService at all?

What would be the best solution for this?

Additional info:
- I am using PHP and Laravel framework, and Stripe as the payment platform

Upvotes: 1

Views: 1894

Answers (1)

Anush
Anush

Reputation: 41

As per the Rest apis published, I presume Cards cannot exist without customers. Hence the rest resource should be named as CustomersResource and all of the above rest api should exist within this class.

This class will have both CustomerService and CardService instances injected.

The next change that you need to make is remove the CustomerRepository dependency on CardService as it breaks the single responsibility principle.

Simply put, Customer service should deal with customer related operations and card service should deal with card related operations. Dont mix both of these.

If you need to build the customer object with its cards information, orchestrate the calls to customer service and card service from the rest resource and send the the same back to the user.

Hope it helps.

Upvotes: 0

Related Questions