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 second case I would be sending a POST request with incomplete fields and in first case I would have one extra endpoint (since I would need /students/{id}/homework
anyway to fetch particular student's homework.)
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}/homeworks
Delete Homework EndPoint:
DELETE https://website.com/api/v1/homeworks/{homework_id}
If A
owns B
, and you want to create a new B
entity, your path will be like /A/{A_Id}/B
.
Boilerplate Request:
POST /ParentEntity/ParentId/ChildEntity
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 in StackOverflow Docs, where your request intention/action is defined in URL suffix instead of being defined by your HTTP method)
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.
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