Let's say I have two objects: Student and Homework. Homework has Student as fk:
CREATE TABLE student (
id serial PRIMARY KEY,
name varchar(100)
)
CREATE TABLE homework (
id serial PRIMARY KEY,
topic varchar(255),
student_id int REFERENCES student(id)
)
Is there any convention for what is the right way to structure the API endpoints for CRUD?
If I want to create a new homework for a student, I could send a json body with student id
{
"student_id": 1,
"topic": "topic
}
to POST https://website.com/api/v1/homework.
Or I could send
{
"topic": "topic
}
to POST https://website.com/api/v1/students/{student_id}/homework and take student id from URL.
In first case I would be sending a POST request with incomplete fields and in second case I would have one extra endpoint (since I would need /students/{id}/homework anyway to fetch particular student's homework.)
CodePudding user response:
I'll recommend the second approach:
A homework can't exist without an associated student.
Best Practices:
What are best practices for REST nested resources?.
And Resource Raming:
https://restfulapi.net/resource-naming/
CodePudding user response:
You have two entities Student and Homework. A Homework entity belongs to Student.
So the more semantically correct approach would be:
Create Homework Endpoint:
POST https://website.com/api/v1/students/{student_id}/homework/addDelete Homework EndPoint:
DELETE https://website.com/api/v1/homeworks/{homework_id}
There are no agreed rules but this is generally a widely followed pattern:
If A owns B, and you want to create a new B entity, your path will be like /A/{A_Id}/B/add.
Boilerplate Request:
POST /ParentEntity/ParentId/ChildEntity/add
Now B was created and you have an id associated with it, so you can directly alter B (say for any mutation operation, POST, DELETE, PUT, PATCH).
DELETE /B/{id}
PUT /B{id}
OR
POST /B/{id}/delete
POST /B/{id}/update
(this one is followed by StackOverflow, where your request intention/action is defined in URL suffix instead of being defined by your HTTP method)
Why do we do directly alter B? Why not do something like:
DELETE /A/{Aid}/B/{Bid}
Because /A/{Aid} would be redundant information. Since it is guaranteed that {Bid} would always be unique even though multiple B entities can belong to a single A entity.
Additional References:
You can see the API pattern Stackoverflow has used for their APIs here for any future reference. https://api.stackexchange.com/docs?tab=category#docs
