Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding and using names for the router #124

Open
mahovich opened this issue Mar 6, 2019 · 9 comments
Open

Adding and using names for the router #124

mahovich opened this issue Mar 6, 2019 · 9 comments
Labels

Comments

@mahovich
Copy link
Contributor

mahovich commented Mar 6, 2019

I propose to make the coolest opportunity - to set a name for the router, similar to how it was done for koa-router

The name can be set as follows:

router.on('GET', '/example', { name: 'example' }, (req, res, params) => {
  // your code
})

// OR

router.on('GET', '/employee/:userId', { name: 'user' }, (req, res, params) => {
  // your code
})

for use:

router.url('example');
// => "/example"

router.url('user', { userId: 2 });
// => "/employee/2"

There are many options for using URL generation, for example, it can be used to generate sitemap.xml, for redirect, and the coolest thing is to use it in html templates.

Why is this cool?
After changing the URL in the code, there is no need to additionally change anything at all! All links placed and used by the code using router.url will automatically change!

Now after changing the URL, you need to make more changes, for example, to make a search and replace in code, scan the site for broken links. But after changing the URL, you can forget to make additional changes at all =)

@mcollina
Copy link
Collaborator

mcollina commented Mar 6, 2019

This is actually a very interesting feature, I used something similar in ruby for a long time, and I think it might be worthwhile adding. However, I do not want to make the name unique on the system.

Specifically:

router.on('GET', '/example', { name: 'example' }, (req, res, params) => {
  // your code
})

// OR

router.on('GET', '/employee/:userId', { name: 'example' }, (req, res, params) => {
  // your code
})

Should not throw, and the system should enable disambiguation.

How do you think we should handle that case?

@mahovich
Copy link
Contributor Author

mahovich commented Mar 6, 2019

This is actually a very interesting feature, I used something similar in ruby for a long time, and I think it might be worthwhile adding. However, I do not want to make the name unique on the system.

Specifically:

router.on('GET', '/example', { name: 'example' }, (req, res, params) => {
  // your code
})

// OR

router.on('GET', '/employee/:userId', { name: 'example' }, (req, res, params) => {
  // your code
})

Should not throw, and the system should enable disambiguation.

How do you think we should handle that case?

IMHO, the name must be unique (as well as the URL).
When copying and pasting a router with an URL, you can forget to change the name and this will be fatal for the project, because many links will become incorrect.
In addition, when creating a new rule, there will be a need to independently verify the uniqueness of the name...

@mcollina
Copy link
Collaborator

mcollina commented Mar 6, 2019

I would prefer to make them non-unique. In Fastify we use an encapsulation pattern, so a full plugin could be mounted with a specific prefix. Unfortunately having a single namespace significantly limits the use of this feature for us.

@mahovich
Copy link
Contributor Author

mahovich commented Mar 6, 2019

The decision on the uniqueness or non-uniqueness of the name may be at the discretion of the author of the repository. In order for this functionality to be in demand for a larger audience (including for a larger number of frameworks), can consider a new option, for example:

const router = require('find-my-way')({
  uniqueName: true
})

// OR notUniqueName

*but this is not necessary - it is more important not to complicate the plugin.

In any case, I will be very happy with any implementation of this functionality, since This is a really necessary opportunity. Earlier I used similar in Python. And I was extremely surprised that most of the javascript routers do not have this.

@jean-michelet
Copy link
Contributor

jean-michelet commented Feb 27, 2024

I would prefer to make them non-unique. In Fastify we use an encapsulation pattern, so a full plugin could be mounted with a specific prefix. Unfortunately having a single namespace significantly limits the use of this feature for us.

I think the router should offer route collection management and allow paths and names to be prefixed by collection.
I'm not making this up, it's actually how the Symfony routing component works: https://github.com/symfony/routing/blob/7.0/RouteCollection.php

Collections could be merged with other collections, at which point we check for name uniqueness.
Then, Fastify could be updated to handle these collections via its plugin system, right?

// Is not a named route, so it's impossible to generate an url from it
fmw.on('GET', '/contact', () => {})

const blogRoutes = fmw.createCollection('/blog', 'blog_')
blogRoutes.get('/new', 'new', (req, res, params) => {})
blogRoutes.get('/:id', {}, 'show', (req, res, params) => {})

const profileRoutes = fmw.createCollection('/profile', 'profile_')
profileRoutes.get('/', '', (req, res, params) => {})
profileRoutes.get('/settings/', 'settings', (req, res, params) => {})

// We check that no route with existing name is merged
fmw.mergeCollection(blogRoutes)
fmw.mergeCollection(profileRoutes)

fmw.url('blog_new', {}, { kind: 'relative_path' }) // /blog/new
fmw.url('blog_show', { id: 1 }, { kind: 'relative_path' }) // /blog/1
fmw.url('profile_', {}, { kind: 'relative_path' }) // /profile
fmw.url('profile_settings', {}, { kind: 'relative_path' }) // /profile/settings

Anyway, I think it should be a separate PR from the URL generation, which is a tricky subject in itself...

@jean-michelet
Copy link
Contributor

Is this feature still considered?

@mcollina
Copy link
Collaborator

I think so, yes.

@jean-michelet
Copy link
Contributor

jean-michelet commented Mar 18, 2024

I'm willing to work on it, but I'd like to know which strategy would suit you best. If my idea of creating collections doesn't fit, I may try* suggest other solutions.

@mcollina
Copy link
Collaborator

let us know! even a draft pr is fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants