7
  1. Suppose you have an event and you wish to add members to that event. Would you design that as event/:event-id/members/ ? or just make it '/members' where you specify the event id in the POST body ?

  2. Dealing with nested entities. For example. An Event has a Mini Event and You wish to add members to that Mini Event. So again, would have something like event/:event-id/mini-event/:mini-event-id/members/ ?

So in the above example, if you wanted to make modifications to member 1 added to that mini event, you'd have to access it like event/:event-id/mini-event/:mini-event-id/members/:member-id which doesn't quite seem right to me because it's 3 level nesting.

Ofcourse, I'd like to know what's the most RESTful way of doing this. The general idea is that do you design APIs the way you have your Database entities modelled(mini events reference the primary key of the Event they are a part of and refer the user primary key as well in the above example) or should it be independent

3 Answers 3

6

You'll find opinionated answers on this because it's subjective to the use case. There is no right answer here. Ideally, you design the API to suit your use case the best.

  1. event/:event-id/members vs /members Questions I'd ask myself: Will the "member" resource stand alone? For example:

    • Will I need to fetch members across events (for say performing analytics) ? I can always GET /members and filter on event-id as a query param.

    • Do I want to add multiple endpoints to support cleaner usage, like POST event/:id/members and GET /members/:id?

  2. I've found that nesting in the manner you mention (3 level) does not scale well for the same reason above - today you nest members under mini-event. Tomorrow, if you need to access members across events (analytics as an example), you'd have to duplicate an endpoint. If it was a root level, again, simply add parameters.

In your case, if a member can belong to both an event and mini-event, you're already having multiple endpoints. Avoid that, it makes documentation harder.

Avoid something like PATCH event/:event-id/mini-event/:mini-event-id/members/:member-id. PATCH members/:id is easier to work with

In conclusion, here is what you can do. Use GET for /members/ and /mini-events/ with query params. POST, PUT, PATCH and DELETE for /events/:event-id/members/:member-id and /events/: event-id/mini-events/:mini-event-id.

Some relevant reading https://martinfowler.com/articles/richardsonMaturityModel.html

0
3

The REST endpoint doesn't necessarily have anything to do with the database schema. At least it shouldn't depend on it, after all it may aggregate data that isn't related directly in the database.

Considering your example, I would expect that GET /event/:eventid/members would fetch all the members of an event, and therefore addition of members would use the same endpoint. It's certainly a lot more RESTful than calling /members and passing the event id as a parameter. That would be a form-based web page style of doing things.

As for your second example, it depends. You might even make mini-events regular events, that just have a parent-child relationship. Then you get rid of one level of nesting and don't need to verify that :mini-event-id is in fact part of :event-id. E.g. /event/:eventid/mini-events/ would list any mini-events related to an event, but they'd still be accessible through /event/:mini-event-id.

3
  • Mini Events have to and have to be a part of an event. So if I were to make them regular events, I'd have to pass in the main event ID and that's not so RESTFUL. So I guess 3 level nesting is a necessary evil?
    – tsaebeht
    Commented Nov 7, 2017 at 11:01
  • @tsaebeht No. In your example you have 3 levels of nesting and you're passing the main event id as well. My proposition would remove 1 level of nesting and promote mini-events to real events (at least from the user point of view). They would just have an implicit relationship with the main-event, so you wouldn't be forced to specify the (redundant) main-event-id.
    – Kayaman
    Commented Nov 7, 2017 at 11:13
  • Unfortunately events and mini-events both have a different schema so I can't take in both of them through the same endpoint. There's a model, a serializer involved.
    – tsaebeht
    Commented Nov 7, 2017 at 15:36
-1

There are some real problems with url parameters in general when you start sending multiple ones

  • How to parse our the end point if you have /events/:eventId and /events/anotherEndPoint/ or /events/:customerId

  • Url length is in practice limited. /events/:guid/childObject/:guid/childObject/:guid... etc cant go on forever

  • Object Trees might not match the query parameters. ie I want miniEventId:123 but I dont know what event it belongs to.

It is RESTfull to mimic a directory style tree structure with your end points, but its more important to have an efficient and easy to use API.

The ugly:

/events/:eventId?withMiniEvents=true

Might mean 500ms off your time to interaction. Would you prefer to be RESTFull? are you doing HATEOAS?

1
  • Erm I'm not too familiar with HATEOS. Currently I've just implemented it as events/:event-id/mini-events/:mini-event-id/hackers but haven't added the RUD endpoints. So you can only GET to list all and POST to create. I guess nesting it 3 times is fine but I've never seen it. Haven't seen something like mini events either so I guess it's fair?
    – tsaebeht
    Commented Nov 7, 2017 at 17:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.