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

feature(common) add @WithAlias route decorator #5117

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

sjones6
Copy link

@sjones6 sjones6 commented Jul 19, 2020

Add @WithAlias decorator which allows arbitrary aliases to be attached to Controller methods and later retrieved in views and resolved to full route path.

Resolves #3743.

I'm not fully convinced of the implementation in router-execution-context.ts especially. This doesn't seem the best way to inject the getUrl helper into render context, so open to suggestions. This could be attached to expressApp.locals to the same effect in express.

Also, open to suggestions on getUrl method name if something else is preferred.

Lastly, does this require fastify support? If so, may require an additional e2e test.

PR Checklist

Please check if your PR fulfills the following requirements:

Docs PR: nestjs/docs.nestjs.com#1400

PR Type

What kind of change does this PR introduce?

[ ] Bugfix
[x] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build related changes
[ ] CI related changes
[ ] Other... Please describe:

What is the current behavior?

New feature/not-implemented.

Issue Number: #3743

What is the new behavior?

A new (non-breaking) decorator is available in @nestjs/common which allows arbitrary aliases to be attached to Controller route handlers, which can then be resolved to the full path of the route.

Additionally, a getUrl(alias: string, params?: object): string method is exposed for MVC views / server-rendered template views.

Example Controller:

import { Controller, Get, Render, WithAlias } from '@nestjs/common';

@Controller('hello')
export class HelloController {
  constructor(private readonly helloService: HelloService) {}

  @Get()
  @Render('hello')
  @WithAlias('hello')
  index() {
    return { message: 'Hello World!' }
  }

  @Get(':id')
  @Render('hello')
  @WithAlias('hello-id')
  index() {
    return { message: 'Hello World!', id: 1 }
  }
}

In your views...

<a href="{{ getUrl('hello') }}">Resolves to `/hello`</a>
<a href="{{ getUrl('hello-id', { id: id }) }}">Resolves to `/hello/1`</a>

Does this PR introduce a breaking change?

[ ] Yes
[x ] No

Please double check—initial implementation decorates response.locals with a getUrl method. This shouldn't cause breakages and should only be additive.

Other information

Some tests and an example were switched from hbs template engine to nunjucks, due to a limitation in hbs which disallows function evaluation in templates. Based on this issue, this seems highly unlikely to change at any time. Nunjucks, on the other hand, evaluates these as you would expect.

Add @WithAlias decorator which  allows arbitrary aliases
to be attached to Controller methods and later retrieved
in views and resolved to full route path.

Resolves nestjs#3743
@@ -164,6 +167,11 @@ export class RouterExecutionContext {
};
}

public bindResponseLocals(response) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment in PR. This feels unlikely to stay, but if kept—need some guidance on proper typing.

@sjones6 sjones6 mentioned this pull request Jul 19, 2020
@coveralls
Copy link

Pull Request Test Coverage Report for Build 0cfed26a-e063-488c-9864-689cb67731c7

  • 38 of 41 (92.68%) changed or added relevant lines in 6 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.02%) to 94.798%

Changes Missing Coverage Covered Lines Changed/Added Lines %
packages/core/router/router-execution-context.ts 5 6 83.33%
packages/core/router/route-alias-resolver.ts 22 24 91.67%
Totals Coverage Status
Change from base Build 8177763b-a5cb-48f7-b162-2e74b53bcd25: -0.02%
Covered Lines: 4957
Relevant Lines: 5229

💛 - Coveralls

@@ -0,0 +1,54 @@
import { join } from 'path';
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currently, didn't see examples in integration tests that rendered html using the @Render decorator unless I'm mistaken. So, this tests that along with new changes..

@kamilmysliwiec
Copy link
Member

Great job!

Can you create a PR to the docs as well? https://docs.nestjs.com/techniques/mvc

sjones6 added a commit to sjones6/docs.nestjs.com that referenced this pull request Aug 2, 2020
Documents the @WithAlias() decorator and getUrl helper introduced in PR nestjs/nest#5117
sjones6 added a commit to sjones6/docs.nestjs.com that referenced this pull request Aug 2, 2020
Documents the @WithAlias() decorator and getUrl helper introduced in PR nestjs/nest#5117
@sjones6
Copy link
Author

sjones6 commented Aug 2, 2020

@kamilmysliwiec , sure thing. Here's a PR for the update to docs: nestjs/docs.nestjs.com#1400.

@kamilmysliwiec
Copy link
Member

Thanks @sjones6! Ill review as soon as possible

@kamilmysliwiec kamilmysliwiec added this to the 7.5.0 milestone Oct 5, 2020
@kamilmysliwiec
Copy link
Member

Apologies for the delay! @sjones6 would you like to jump in once again and add an e2e test for fastify too (+ update an example)? This should be the last thing we need in order to get it merged :)

@sjones6
Copy link
Author

sjones6 commented Oct 30, 2020

@kamilmysliwiec , sure—I'll get those in an ping once it's updated. (Looks like some conflicts to resolve too.)

@sjones6 sjones6 closed this Oct 30, 2020
@sjones6 sjones6 reopened this Oct 30, 2020
@kamilmysliwiec kamilmysliwiec removed this from the 7.5.0 milestone Nov 2, 2020
}
public register(alias: string | Symbol, basePath: string, path: string[]) {
if (this.aliasMap.has(alias)) {
throw new Error(`Conflict ${alias} already registered`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to suggest a new Error object here, like RouterAliasError or something else, Error it too much generic

Copy link
Contributor

@cojack cojack Nov 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RouteNameError

private stripSlashes(str: string) {
return str.replace(/^\/?(.*)\/?$/, '$1')
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at the end of the files, there should be a new line

@@ -147,6 +147,7 @@
"mysql": "2.18.1",
"nats": "1.4.9",
"nodemon": "2.0.4",
"nunjucks": "^3.2.1",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the reason to put that here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it's for a new integration test. As it's in devDeps it should be fine

@cojack
Copy link
Contributor

cojack commented Nov 22, 2020

Tbh WithAlias decorator might be misleadin, I would like to suggest smth like RouteName. There is a second PR that will add ap possibility to create an alias to specific path, so looking for router alias might be difficult, pointing to two different actions.

@cojack
Copy link
Contributor

cojack commented Feb 2, 2021

Tbh WithAlias decorator might be misleadin, I would like to suggest smth like RouteName. There is a second PR that will add ap possibility to create an alias to specific path, so looking for router alias might be difficult, pointing to two different actions.

Nobody care?

@CDaxi
Copy link

CDaxi commented Feb 19, 2021

@cojack: From my point of view RouteName will be the better name and i really like to see this feature in nestjs.
It will be really handy to change route paths and attributes only on one place - the controller.

@omcg33
Copy link

omcg33 commented Apr 5, 2021

Any steps to merge pr?

@DimitriSauvage
Copy link

Hello @cojack @sjones6 @kamilmysliwiec and others,

I agree with cojack, @RouteName is a better name which is more releavant than @WithAlias.
Except this little point, this is an awesome feature ! Thanks

@ivmilicevic
Copy link

I'm sorry but will this get merged? It seems like thing it's waiting on is name change

@rpCal
Copy link

rpCal commented Sep 12, 2021

@sjones6 Thank you very much for the code.... @kamilmysliwiec @cojack Any updates soon? :)

@fadillzzz
Copy link

Any updates on this? Seems like too good of a feature to not have as part of the official release.

@spearmootz
Copy link

yes please. this would be very useful for migrating from symfony

@marcelobrk
Copy link

What is missing for this to be merged?

@engAmirEng
Copy link

Is this feature ever going to be added?

@MrOplus
Copy link

MrOplus commented Oct 28, 2022

is this pr going to get merged after almost 2 years?

@corentinalcoy
Copy link

@kamilmysliwiec @sjones6, It is a really nice feature, Is this PR going to be merged?

@orige
Copy link

orige commented Jul 11, 2024

Any news on this?

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

Successfully merging this pull request may close these issues.

Named routes