I'm currently working on a frontend application where I need to display information about authors. Each author can have multiple child objects (e.g., books), and I also need to display information about sibling objects (e.g., publishers related to the authors).
Here's the challenge I'm facing:
Displaying child objects: I can easily retrieve authors and their books using an endpoint like /authors, which seems to fit the RESTful design principles.
Displaying sibling objects: however, I'm unsure how to effectively include sibling objects like publishers (or any other related data that doesn't directly belong to the author but is related in some context) without violating REST principles.
Here are the options I'm considering:
Option 1: include all related data (authors, books, and sibling objects) in the /authors endpoint. This approach seems straightforward but feels like it's not adhering to RESTful design because sibling data isn't directly part of the author resource. Additionally, I'm concerned about the potential increase in payload size, which could impact performance.
Option 2: make separate API calls for each author to fetch sibling data from their respective endpoints. This could lead to performance issues due to multiple network requests.
Option 3: implement a backend-for-frontend (BFF) pattern to tailor the API responses specifically for the frontend needs, bypassing strict REST conventions. However, this approach requires significant changes to our current architecture.
I'm looking for a way to add the siblings to my results without damaging performance or increasing server/network load for designing this API. How can I structure the API to efficiently retrieve both child and sibling objects while maintaining a RESTful approach? Are there any industry-standard patterns or strategies to handle this situation?
Any insights or recommendations would be greatly appreciated!
In the space of this answer I presume that you aim for 1. performance increase 2. network and load reduce
In order to address both, you will need to support a hydrated and a non-hydrated version for your endpoint.
So, author and book are both part of the core logic of the endpoint, that is, all usages will need the authors and the books, but sometimes publishers (and other entities) are needed, sometimes they are not needed.
Hence, you can specify a parameter for your endpoint that would list the entities the caller of the API wants to hydrate with. An example value could be
publisher,blublabli,category
So, you break up the actual values with the separator (,
in this case) and validate all entities the caller of the API specified to hydrate with. If 1. the entity exists 2. It is valid for this endpoint 3. The caller is allowed to load that entity, then you hydrate with that entity. Otherwise you don't hydrate with that entity.
Make sure that you are consistent in the format that you return, it would be nice to have an array for hydrated entities inside the object of each author and that would contain key-value pairs of entity name and array of hydrated objects of that entity.
This would allow you to be 1. efficient when you are to load with hydrated values, as you may construct your inner things under the hood in an optimal manner, with optionally joining to some tables depending on necessities, 2. reduce server load and network load by not hydrating siblings where you don't need them.
Of course you may implement an end point for getting the publisher of a book too, which will also have legitimate use-cases.