I have been dealing with this problem many times and after reading different articles, I still dont know which is the best approach
Lets say I have this model:
-Author -Category -Book
A book cannot exists without an author and a category, so when talking about a post endpoint for a creating a new book, I have fouroptions:
myapi/v1/authors/{authorId}/category/{categoryId}/boooks (nesting entities)
myapi/v1/{authorId}/{categoryId}/boooks (just the foreign keys as path parameters)
myapi/v1/books/?author={authorId}&category={categoryId} (using query params)
myapi/v1/books (using a request DTO containing both author and category id)
Which one of these options is the best? Option 1 gives a lot of information about the relations, but it can be difficult to mantain as relationships grow (very long URI)
Options 2 and 3 looks fine to me, but I dont know if it is the proper approach
Option 4 is easier to read and mantain, but it does not provide information about how book i related to author and category
I am open to advice. Thanks!
Trying to build a proper and readable post endpoint for a post rest api endpoint
CodePudding user response:
#4 in my opinion. URL doesn't have to give information on your data structure
CodePudding user response:
The context of my answer that we are talking about a custom approach, not a standard like OData.
- ok, if you correct the typos, hard to follow if you mix plural (authors, books) and singular (category) forms.
- definitely not, hard to guess and remember
- ok
- for simple requests like this it does not make sense to use POST or SEARCH, it is better to use them for more complex search
I vote on the 3rd one, because there is no hierarchical relationship between the authors and the categories. I guess one author can post to multiple categories and one category can contain multiple authors, so it is n:m relationship in database terms. For most of the cases I like the 3rd solution, because it is simple. If you have a unique id for the resource, then it is just {type}s
, /{type}s?filters={filters}
, /{type}s/{id}
, /{type}s/{id}/{property}
. If you have many different resource types, then {type-group}/{type}s
. Filters can be JSON serialized and URI encoded if you don't care about readability, for machines it is readable after all.
What most people don't grasp, that the webservice is a service, it has operations the consumers call and it is not a data structure. These endpoints identify which operation will handle the request, not which data record will be accessed in the database. The latter one is because we are talking about a certain type of operation, but I can easily write GET https://example.com/calendar/api/v1/time/now
and it won't touch the database at all.
CodePudding user response:
I will go for the fourth option.
myapi/v1/books (using a request DTO containing both author and category id)
with POST request, using request DTO for sending data is a good solution most of the cases as a rule of thumb.
And importantly, using request DTO, will allow you to use the same api for single creation or bulk creation of books, you just need to send a list in the request DTO for multiple book creation in one api call.