ephios-dev/ephios

Make Participation API Consistent and Use Fewer Calls

Closed this issue · 4 comments

Is your feature request related to a problem? Please describe.
We're building a third-party service (https://github.com/benbals/pretix-fsr-validation) that want's to verify if a user (identified by email) has at least one shift in a specified "event" (though our event consists of multiple ephios events). This has to happen on page load in our application and thus must be fast not to negatively impact user experience.

Currently that takes at least but potentially arbitrarily many requests against your API (one to swap an email address to a ephios id which is used nowhere else and potentially arbitrarily many to find a relevant participation in the non-filterable list).

Also, the current API is inconsistent. As a developer, if the routes

/users/me/
/users/{id}/
/users/by_email/{email}
/users/{id}/participations

exist, I would expect the routes

/users/me/participations
/users/by_email/{email}/participations

to exist as well. As it is right now, the routes are confusing because they have intransparent "holes" in them.

Describe the solution you'd like
Provide the routes

/users/me/participations
/users/by_email/{email}/participations

Describe alternatives you've considered

  • If ephios doesn't have these routes and I'd be forced to slow down user facing page loads by realistically 200ms-600ms without need, I'd likely rather just expose the database to my application and perform SQL requests instead of using the API.
  • I could maintain a fork that includes the APIs we need to make our infrastructure work together well. We've done this with the Engelsystem (https://github.com/fsr-de/engelsystem) for a while and would like to move away from that, but imo not at the price of UX.

Additional context

  • E-Mail addresses are unique by your database schema so forcing external users to use and keep track of your internal primary keys seems unnatural and is cumbersome for developers who most likely identify users they are interested in by the only other format you accept: email addresses.

This is a follow-up to #1222 as in my view as the developer of indented first consumer of the API @jeriox proposed, the implementation does not solve our use case without degrading user experience in a way I'd rather hack around then accept.

Hey Ben,
we know our API is not fully fledged and all, but we are transparent about available endpoints with the (auto-generated) documentation.

I do consider an id the better identifier, as email addresses in ephios can change. IDs are also what you get for every other data type in our API. It's just common practice.

I understand you don't want any extra steps or asynchronous calls in your pretix plugin. I timed requests to the users/id/participations endpoint on our production infra and it takes well under 100ms for a user with 5 participations (so that's the added delay with having to make a second call), and that's via the internet, not to a local server!

I do agree filters could make the new endpoints more useful, although it would not speed up your upcoming deployment situation as there are not many "old" participations that would mean you'd need to paginate.

If, having said all that, you're still unhappy with the endpoints currently offered, you always have the option to provide your own custom endpoint using an ephios plugin, no need to run your own fork!

I do consider an id the better identifier, as email addresses in ephios can change.

This argument only holds if the external user is using your internal pk as their user identifier, which, at least for our use case that's non-sensical. I also find that the "I have a user on my end and I want to find them in ephios" use case is likely generally relevant, but you know your user base better.

IDs are also what you get for every other data type in our API. It's just common practice.

By common practise you mean inside your API? Because generally my understanding is that having inconsistent sub-routes is a REST anti-pattern. (i.e., if /a returns the same object as /b, then /a/c should return the same object as /b/c).

I do agree filters could make the new endpoints more useful, although it would not speed up your upcoming deployment situation as there are not many "old" participations that would mean you'd need to paginate.

Right now, that's true. But one of our (if not the main) motivation to switch away from the Engelsystem is not to have to do one-shot deployments, that can only handle a single event. So while this might be true right now, this is not necessarily true indefinitely. Also the added code complexity would need to be implemented now to avoid running into weird bugs where the check fails for users with many participations in the future. This is especially the case since to optimise network latency, my ideal scenario would include setting limit to one on the request.

If, having said all that, you're still unhappy with the endpoints currently offered, you always have the option to provide your own custom endpoint using an ephios plugin, no need to run your own fork!

Yeah, if this doesn't land in core, then I'll guess we do that though I don't like it from a maintenance overhead perspective (especially after @jeriox and me leave).

I understand you don't want any extra steps or asynchronous calls in your pretix plugin. I timed requests to the users/id/participations endpoint on our production infra and it takes well under 100ms for a user with 5 participations (so that's the added delay with having to make a second call), and that's via the internet, not to a local server!

I've tested this both against other endpoints on our production deployment and against these endpoints locally and cannot replicate this low latency. Over the network, it's around 200ms per request.

Also I disagree with assessment that they are 'asynchronous'. They might be technically be true from a whole-server perspective, but from the perspective of a single handled request they are both sequential and blocking.


Tbh the only arguments you mentioned against implementing this are

  • it might encourage "down data-stream" API consumers to rely on the wrong user identifier
  • it's only a medium amount of annoyance to work around this

Or am I missing something?

we decided on keeping the endpoints as they are and implemented filters in #1249