Server API design

I’m continuing our conversation here.

As we extend our REST API, used mainly by the CLI at this point, and potentially productized and interacted with by developers, there are a couple of things that I think we should form an opinion on:

  • Flat or nested design: We are trending towards a nested design of routes, mostly under a project, but I wonder if we want to continue down that path, or move more towards a flat design, similar to Stripe’s, where we flatten all the domain resources, and use query params to filter. For example, to get the runs of a project, we’d do /api/runs?project_id=... instead of /api/projects/:project_id/runs. I lean on the flattening, but I’d like your thoughts.

  • Unique identifiers: When identifying some resources, like accounts and projects, we use their handles, like we do when designing UI routes. I think that makes sense in that context, but is it in the API context? (e.g. /api/:account/:project vs /api/projects/:project_id. Perhaps we can agree it’s ok to do so for those two resources, since that’s how clients refer to them, through their handle or the full handle account_handle/project_handle, and then use the DB UUIDv7 identifier for the rest of the resources. We should consider migrating the resources using an ID other than UUIDv7 at some point.

Thoughts?

I slightly prefer the latter as it’s closer to how frontend URLs are structured. It’s also the model GitHub is following: REST API endpoints for pull request review comments - GitHub Docs

I wouldn’t have a strong preference if we were starting from scratch, but I don’t think the API migration is worth it at this point for an API structure that’s more of a matter of taste rather than one strategy having clear benefits over the other.

Yes, I think it’s fine in the case of accounts and projects. This is also the model of the GitHub API. I do think anything else should be using UUIDv7 and we should certainly migrate resources using the integer ID to it.