iver-wharf / wharf-api

Wharf backend written in Go
MIT License
1 stars 0 forks source link

Add URL slug to projects #149

Open applejag opened 2 years ago

applejag commented 2 years ago

Currently you have to use ID to get a single project.

Want to add so we can look them up on some kind of normalized name, such as a URL slug dedicated for each project.

They would still have their IDs behind the scenes.

  1. Add indexed nameSlug and groupNameSlug columns to project
  2. Add migrations to add slugs to existing projects
  3. Ensure slug is added on project insertion
  4. Ensure slug is updated when the project name or group is updated

Maybe we want to have a normalized slug as well so that we can make fast case insensitive lookups.

Example project:

Column Value
name My Project
groupName My Group/Stuff
nameSlug My-Project
nameSlugNorm my-project
groupNameSlug My-Group-Stuff
groupNameSlugNorm my-group-stuff

In queries like GET /api/project?groupNameSlug=My-Group-Stuff, do the actual lookup on the groupNameSlugNorm field, but use the groupNameSlug in the response object. This way the frontend can redirect to its "canonical" slug with cases preserved.

All of this is to allow wharf-web to use project slugs in the URL instead of project IDs. So the URLs would be http://localhost/project/My-Group-Stuff/My-Project/builds instead of http://localhost/project/123/builds

Need to consider how to do the project data lookups as well. We perhaps don't want to add another set of API endpoints just for using the slugs instead of the IDs. One idea is to let the wharf-web rely on querying GET /api/project?nameSlug=...&groupNameSlug=... for fetching the project metadata (including ID) via something like route resolvers and then use that in future requests for stuff that targets the project like "start a new build". (explored in https://github.com/iver-wharf/wharf-web/issues/117)

Alexamakans commented 2 years ago

Since group and project names (nor the combination) are not guaranteed unique between remote providers, how would we do this?

I can't really think of an elegant way to resolve that issue. We would have to somehow specify which remote provider the project should've come from I believe.

EDIT: Oh, I see. The ID behind the scene is what kinda fixes it. I misunderstood when reading first. GET /api/project?groupNameSlug=My-Group-Stuff would still be allowed to return several projects, same as before, then right?

But how would the frontend know which project data to send if you click the link http://localhost/project/My-Group-Stuff/My-Project/builds though?

Maybe keep the project ID in the URL, and just add My-Group-Stuff/My-Project/, like: http://localhost/project/420/My-Group-Stuff/My-Project/builds ?

applejag commented 2 years ago

Suggest relying on route guards/resolvers in Angular (https://www.pluralsight.com/guides/prefetching-data-for-an-angular-route) for the frontend to get the ID without needing the ID in the URL.

The provider collision is a good point. We discussed this a while ago and we landed in the suggested solution of relying on the provider's host name, such as:

http://localhost/project/github.com/iver-wharf/wharf-api/builds

There's this whole other idea of merging all providers so to ensure we don't have duplicates on a per-hostname basis.

This issue grew a little, and needs some more dedicated planning.

Perhaps something like this would be best:

wharf-api-graph

The Uniq is referring to a unique index constraint

Alexamakans commented 2 years ago

Yeah that's a fine alternative for the URL I think 👍🏻

There's this whole other idea of merging all providers so to ensure we don't have duplicates on a per-hostname basis.

+1 for merging providers from me.

Perhaps something like this would be best:

I wonder, what would happen if we had that and somebody imported from https://gitlab.com/api/v4 and then from https://gitlab.com/api/v5? 🤔

Not that we have support for that currently, I think...

applejag commented 2 years ago

I wonder, what would happen if we had that and somebody imported from https://gitlab.com/api/v4 and then from https://gitlab.com/api/v5? thinking

Not that we have support for that currently, I think...

Those two should be handled as the same provider, and let the wharf-provider-gitlab use the highest one available by trying to negotiate the version with the provider. Or just only stick with v4 if they don't plan on deprecating it.

Actually none of the providers should need the path at all. So the "URL" column is actually excess.

Oh, and we probably don't want http://localhost/project/api.github.com/iver-wharf/wharf-api, so there should maybe be a "slug hostname" and "API hostname" difference.

applejag commented 2 years ago

Don't want to spend too much thinking on this right now though as there are other things that are higher prio.

Us moving to proper auth instead of tokens is also something to think about.

This issue is mostly to not forget, but let's put a pin in this for now.

Good discussion though.