nestjsx / nest-router Goto Github PK
View Code? Open in Web Editor NEWRouter Module For Nestjs Framework 🚦 🚀
License: MIT License
Router Module For Nestjs Framework 🚦 🚀
License: MIT License
Hi @shekohex,
Do you know if the nest-router package works in V5?
We are are trying upgrade application and we are having issues in our authentication middleware.
In v4, req.path = the full relative path to an item eg /api/private/users
In v5, req.path = "/"
resolve(...excluded: Route[]): FunctionMiddleware {
return (req, res, next) => {
const isExcluded = excluded.filter(route => {
let excluedPath = route.path == req.path;
return excluedPath
}).length > 0;
}}
Not sure if this is a Nest issue or a router issue.
Regards,
Tarek
Could you create more complex example of usage your router, please?
For example
Prefix 'api/v1'
public route
PostsModule -> view post
private route
PostsModule -> sendPost
Thank you in advance!
If we use nest router with swagger module. Swagger module doesn't know the correct routes. Is it even possible to implement this?
Hi Shekohex,
after some trial and error I think nest-router is having issues when a globalPrefix is set in bootstrap function.
Let's say my routes look like this:
const routes:Routes = [
{
path: '/test',
module: TestBackendModule
}
];
Combined with this
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.setGlobalPrefix(`api`);
await app.listen(3333);
}
Neither calls to /api/test nor calls to /test could be routed successfully.
After removing the call to setGlobalPrefix, calls to /test were routed to the TestBackendModule.
Is this behaviour intended? If so, may I recommend to add a note to the Readme.
Can you please change "childrens" to "children"? There's no such word as "childrens" in the English language :)
Hi,
So I recently installed this router, and I am trying to use a validation pipe with my post routes to validate input. Unfortunately, when I set up the validation router, nothing seems to happen, and people can specify whatever values they want.
In this case, I request /test with a body of
{ "string": true }
I expect this to error but it does not.
Minimal reproduction of the problem
Test DTO
import { IsString } from "class-validator";
export class TestDTO {
@IsString() public readonly string: string;
}
Test Controller
@Controller()
export class TestController {
@Post("/test")
public testing(@Body(new ValidationPipe()) test: TestDTO): string {
return test.string;
}
}
Are validationpipes different when using this router?
5.4.0
to 5.4.1
.This version is covered by your current version range and after updating it in your project the build failed.
@nestjs/core is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
When I want to do multiple versions on my routes, and I reuse a controller for certain version, it only takes the latest version.
const routes: Routes = [
{
path: 'v1',
children: [
{
path: Route.COMIC,
module: ComicModule,
},
{
path: Route.MY_COLLECTION,
module: MyCollectionModule,
},
],
},
{
path: 'v2',
children: [
{
path: Route.COMIC,
module: ComicModule,
},
{
path: Route.MY_COLLECTION,
module: MyCollectionModule,
},
],
},
];
So I miss, the v1 mapping
Hello!
I have the issue which was discussed but can't apply the suggested resolving.
I have two DELETE like bellow :
@delete('/agent/:id')
async deleteInactiveAgentFromProfiles(
@param('id') id: string,
): Promise {
return this.profilesService.deleteInactiveAgentFromProfilesById(id);
}@delete(':id')
async deleteProfile(@param('id') id: string): Promise {
return this.profilesService.deleteProfileById(id);
}
My ids smt like this /^UPC-[0-9A-F]{19}-[0-9A-F]{1}$/
So regarding this issue in second DELETE I have to do smth like this
@Delete('/:id(^UPC-[0-9A-F]{19}-[0-9A-F]{1}$)/')
But it doesn’t work.
What I'm doing wrong?
Thank for helping.
If I use nest-router, when I add a logger middleware for ApplicationModule, the middleware not work.
But when I remove nest-router, middleware worked. Is there any conflicts between nest-router and middleware?
// app.module.ts
import { Module, NestModule, MiddlewaresConsumer, RequestMethod } from '@nestjs/common';
import { RouterModule } from 'nest-router';
import { routes } from './routes';
import { SoftwareModule } from './software/software.module';
import { loggerMiddleware } from './logger.middleware';
@Module({
imports: [RouterModule.forRoutes(routes), SoftwareModule],
})
export class ApplicationModule implements NestModule {
configure(consumer: MiddlewaresConsumer): void {
consumer
.apply(loggerMiddleware)
.forRoutes({
path: '/api/v2',
method: RequestMethod.ALL
})
}
}
// logger.middleware.ts
export const loggerMiddleware = (req, res, next) => {
console.log(`Request...`);
next();
};
// routes.ts
import { Routes } from 'nest-router';
import { SoftwareModule } from './software/software.module';
const v2_modules = [
SoftwareModule,
]
const route = v2_modules.map(module => {
return {
path: '/api/v2',
module,
}
})
export const routes: Routes = route;
Hey there,
this is exactly what I need. Great job! But what about naming this package like @nestjs/router
giving it a more integral role in the whole framework like @angular/router
.
How to use child routes with parent modules?
The only way I managed to make the child route work was:
// app.routes.ts
export const routes: Routes = [{
path: 'banks',
module: BanksModule,
children: [
{
path: 'account',
module: BankAccountsModule,
},
],
}];
@Module({
imports: [
RouterModule.forRoutes(routes),
BanksModule
BankAccountsModule // Child module is imported directly in AppModule
]
})
export class AppModule {}
app.module
| banks.module
| bankaccounts.module
```ts
@Controller('/banks')
export class BanksController implements CrudController<Bank> {
@Controller()
export class BankAccountsController implements CrudController<BankAccount> {
This http request below return all bank accounts
GET /banks/account
but...
GET /banks/
return:
{
"statusCode": 404,
"message": "Cannot GET /banks",
"error": "Not Found"
}
All other ways return `/banks` but `banks/account` returns:
```json
{
"statusCode": 400,
"message": "Invalid param id. UUID string expected",
"error": "Bad Request"
}
but if you try to use nested module, it will to fail.
@Module({
imports: [
RouterModule.forRoutes(routes),
BanksModule
]
})
export class AppModule {}
@Module({
imports: [
BankAccountsModule // Child module is imported in your parent module
]
})
export class BanksModule {}
app.module
| banks.module
| bankaccounts.module
I already tried to remove and add tags to BankAccount Controller
but nothing makes it work the second way.
I think it is the right way to implement nested routes with parent modules.
But how to make this work with nest-router
?
Update: I think that is any error with Nestjs Crud library.
I'm submitting a...
[ ] Regression
[ ] Bug report
[x] Feature request
[x] Documentation issue or request
Hello, I return my collection of ninjas with a get in /ninjas
.
I add a new ninja with a post in /ninjas
.
I consult and modify the data of a ninja in /ninjas/id
.
The ninjas can have cats.
I wish I could consult the cats of a ninja with a get in:
/ninjas/id/cats
add a new cat to a ninja with a post in /ninjas/id/cats
I would also like to be able to consult and modify a ninja's cat in /ninjas/id/cats/id
It's possible?
I found this link that has something similar:
#17
but if I do what is exposed there, the post and get methods stops working in /ninjas
How can I make everything work?
And for example in the URL
/ninjas/12/cats/10
Get the data of the cat 10 and its owner (the ninja 12)
Is there any plan to support root level routing?
It seems not at the moment.
I was thinking of separating normal user namespace and admin user space like following, but got result of having //users
as result where I expected to have /users
. This //users
is really accessible by //users
and doesn't treated as /users
.
It would be nice if I could manage all routes including root level in this route configuration.
route setting code
export const routes: Routes = [
{
path: '',
children: [
UserModule,
],
},
{
path: 'admin',
children: [
AdminUserModule,
],
},
]
part of log output
[RoutesResolver] UserController {//users}
[RoutesResolver] AdminUserController {/admin/users}
5.3.11
to 5.3.12
.This version is covered by your current version range and after updating it in your project the build failed.
@nestjs/common is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
Hi there!!
Based on your example:
const routes: Routes = [
{
path: '/ninja',
module: NinjaModule,
children: [
{
path: '/cats',
module: CatsModule,
},
{
path: '/dogs',
module: DogsModule,
},
],
},
];
Is it possible a request like this: /ninja/01008/cats or this /ninja/n01/dogs ?
Thanks for your work!
We are using https://github.com/nestjsx/nest-router#params-in-nested-routes, and it is working fine for the most part. We have an issue with https://github.com/nestjs/swagger, however. It does not recognize the nested route parameter. As you can see below, it is not declared in swagger.json.
Excerpt from /api-json
:
"/pets/{context}/cat/{name}": {
"get": {
"operationId": "CatController_getCatByName",
"parameters": [
{
"name": "name",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": ""
}
},
"tags": [
"Cat"
]
}
},
import { RouterModule } from 'nest-router';
import { Module } from '@nestjs/common';
import { PetsModule } from './pets';
@Module({
imports: [
RouterModule.forRoutes([
{
path: '/pets/:context',
module: PetsModule,
},
]),
PetsModule,
],
controllers: [],
providers: [],
})
export class AppModule {}
import { Controller, Get, Param } from '@nestjs/common';
import { Cat } from './cat';
import { ApiTags } from '@nestjs/swagger';
@Controller('cat')
@ApiTags('Cat')
export class CatController {
@Get(':name')
getCatByName(@Param('name') name: string): Cat {
}
}
5.7.3
to 5.7.4
.This version is covered by your current version range and after updating it in your project the build failed.
@nestjs/core is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
It is kind of hard to defined Guards (e.g., AuthGuard) at global level but exclude at specific route with standard @nestjs.
it would be nice if this package provide a way to define canActivate
with route definition so that we can have some control over customizing enforcing guards declaratively.
5.5.0
to 5.6.0
.This version is covered by your current version range and after updating it in your project the build failed.
@nestjs/core is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:
.travis.yml
If you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.
Greenkeeper has checked the engines
key in any package.json
file, the .nvmrc
file, and the .travis.yml
file, if present.
engines
was only updated if it defined a single version, not a range..nvmrc
was updated to Node.js 10.travis.yml
was only changed if there was a root-level node_js
that didn’t already include Node.js 10, such as node
or lts/*
. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.For many simpler .travis.yml
configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
Is there planned support for host/subdomain?
What is the difference of this module compared with the nestjs core RouterModule ?
So far both seem to work equally the only issue I encountered with the nestjs core RouterModule was that during e2e tests the mapping was lost when closing the app after each test, the same does not happen with the nestjsx RouterModule.
I want to use something like @Version in v7
Issue:
In the Logs, when Nestjs goes to compile, an additional slash is being added before the module's controller. This can be verified by hitting the url route. If one were to go to /api/v1/auth/
, you would get a 404, but the path in the url /api/v1/auth//
works as a status 200.
Terminal Log Path on Compiling:
[Nest] 21099 - 3/6/2019, 7:27:44 PM [RoutesResolver] AuthController {/api/v1/auth//}: +0ms
What it should be:
[Nest] 21099 - 3/6/2019, 7:27:44 PM [RoutesResolver] AuthController {/api/v1/auth/}: +0ms
Router Object:
`
// ROUTES
const routes: Routes = [ {
path: '/api',
children: [ {
path: '/v1',
children: [
{ path: '/auth', module: AuthModule }
]
}]
}];
`
Controller:
`
import { Controller } from '@nestjs/common';
@Controller()
export class AuthController {
@Get()
returnSomething() {}
}
`
Auth Module:
`
import { Module } from '@nestjs/common';
// Controllers
import { AuthController } from './auth.controller';
@Module({
controllers: [ AuthController ]
})
export class AuthModule {}
`
Here's my file of defined routes:
export const routes: Routes = [
{
path: Path.AUTH,
module: AuthModule,
},
{
path: Path.HEALTH,
module: HealthModule,
},
{
path: Path.MENU,
module: MenuModule,
},
{
path: Path.USERS,
module: UsersModule,
children: [
{
path: Path.CAMPUS_USERS,
module: CampusUsersModule,
},
],
},
];
The problema appears when I try to access some specific endpoints from the CampusUsersModule
(to be more specific, all endpoints that doesn't have path param following the name of collection.
To visualize the problem I'll list the endpoints that are in conflict:
Endpoints from UsersModule:
-1 GET /api/v1/users
-2 GET /api/v1/users/{id}
Endpoints from CampusUsersModule:
-3 GET /api/v1/users/campus
-4 POST /api/v1/users/campus
From what it can be appreciated, the endpoints 2 and 3 have the same format and method. The resolver that decides at which route handler derive the request is misplacing request 3 and sending it to 2.
The solution would be to evaluate first the endpoints more "specifics", and then ascend the tree to the endoints more general.
So, the order of resolution should be:
GET /api/v1/users/campus -> First evaluate any endpoint that does not have any path param
GET /api/v1/users/{id} -> Then evaluate any endpoint that is in some way more general
In my application I have an entity 'stories', that I want to be able to reach from the top level of routes (e.g. api/v1/stories
) but also to access it nested so that it can have parameters for another entity, e.g. api/v1/boards/:boardId/stories
.
Is this possible with the current build? I've tried out different ways of organising them but it seems that multiple declarations of a module will overwrite any previous ones.
For example one setup that I tried was:
const routes: Routes = [
{
path: '/stories',
module: StoryModule
},
{
path: '/boards',
module: BoardModule,
children: [
{
path: '/:boardId/stories',
module: StoryModule
}
]
}
];
In this case the boards route and nested stories route works, but the top level stories route does not. If i place the top level stories route after the nested route, that one works and the nested one doesn't.
If controller path does not start with a '/', resolvePath of RouterModule does not work for middlewares.
Example:
@Controller('foo') // No '/' at the beginning!
export class FooController {
@Get('hoo')
doHoo() { return 'hoo' }
...
}
@Injectable()
export class FooMiddleware implements NestMiddleware {
resolve(...args: any[]): MiddlewareFunction {
return (req, res, next) => {
console.log('this message will not be logged... so sad..');
next();
};
}
}
@Module(...)
FooModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(FooMiddleware).forRoutes(
RouterModule.resolvePath(FooController ),
);
}
}
So may proposal is to do something like:
public static resolvePath(controller: Type<Controller>): string {
const controllerPath: string = Reflect.getMetadata(PATH_METADATA, controller);
const modulePath = RouterModule.routesContainer.get(controller.name);
if (modulePath && controllerPath) {
return validatePath(modulePath + (!controllerPath.startsWith('/') ? '/' : '') + controllerPath);
} else {
throw new UnknownElementException();
}
}
I'm having a bit of trouble keeping my route definitions modular.
In this repro repo I have the AppModule
that says hello when /prefix/hello
is called. But I intended the SubModule
to respond when /prefix/sub/hello
is called. But if I just use @Controller('sub')
in the SubController
, then it responds only to /sub/hello
.
Now, I have read a bit of the original discussion with kamilmysliwiec and understand that modules are not meant to map directly to the paths. But right now it feels like needing to declare all routes in a single module hurts modularity.
Is there a way to prefix all controllers of a module as well as their imported controllers?
Having my routes defined like this,
RouterModule.forRoutes([{
path: 'posts',
module: PostsModule,
children: [
{
path: 'random',
module: PostModule
},
{
path: '/:postId(\\d+)/',
module: PostModule
}
]
}])
I'm able to access /posts/2736
, but I'm not able to access /posts/random
.
I tried changing the order of the child routes, but it resulted in not being able to access /posts/2736
anymore.
It does work, however, when I define the routes directly inside the PostsController
.
@Get('random')
findRandom() {
return 'Random post.';
}
@Get(':postId(\\d+)')
findOne() {
return 'Post by id.';
}
Any way to solve this? Thanks in advance!
It scratched my head many times and I also tried to find the information on web but nothing answered my question so I'm finally posting it here.
Are there any drawbacks of adding version information to the controller itself instead of doing it to the module level ?
Sample code
@Controller("v1/user")
UserV1Controller
{
@Get("profile")
userProfile()
{
}
}
@Controller("v2/user")
UserV2Controller
{
@Get("profile")
userProfile()
{
}
}
**In module**
@Module({
controllers:[UserV1Controller, UserV2Controller],
})
Different routes
v1/user/profile
v2/user/profile
PS: I'm not questioning the existence of nest-route package, I find it amazing and appreciate the effort and knowledge used in implementing this. My question is specific to api versioning only.
5.3.11
to 5.3.12
.This version is covered by your current version range and after updating it in your project the build failed.
@nestjs/core is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
Right now I’m nest you have to options to apply interceptors per controller or globally. But it would be nice to have it per route.
In our solution each route (module) has it's own translation file. This to keep thing organized and flexible.
But to apply one a interceptor per route isn’t possible yet.
I don’t know if this belongs to this library, or nest itself?
Cause if nest supported interceptors per module we wouldn’t have this problem.
If anyone knows an solution let me know
23.1.4
to 23.10.0
.This version is covered by your current version range and after updating it in your project the build failed.
ts-jest is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
ts-jest
, reloaded!ts-jest
Slack community where you can find some instant helpjest
, typescript
and babel
versionsThe new version differs by 293 commits.
0e5ffed
chore(release): 23.10.0
3665609
Merge pull request #734 from huafu/appveyor-optimizations
45d44d1
Merge branch 'master' into appveyor-optimizations
76e2fe5
ci(appveyor): cache npm versions as well
191c464
ci(appveyor): try to improve appveyor's config
0f31b42
Merge pull request #733 from huafu/fix-test-snap
661853a
Merge branch 'master' into fix-test-snap
aa7458a
Merge pull request #731 from kulshekhar/dependabot/npm_and_yarn/tslint-plugin-prettier-2.0.0
70775f1
ci(lint): run lint scripts in series instead of parallel
a18e919
style(fix): exclude package.json from tslint rules
011b580
test(config): stop using snapshots for pkg versions
7e5a3a1
build(deps-dev): bump tslint-plugin-prettier from 1.3.0 to 2.0.0
fbe90a9
Merge pull request #730 from kulshekhar/dependabot/npm_and_yarn/@types/node-10.10.1
a88456e
build(deps-dev): bump @types/node from 10.9.4 to 10.10.1
54fd239
Merge pull request #729 from kulshekhar/dependabot/npm_and_yarn/prettier-1.14.3
There are 250 commits in total.
See the full diff
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
Plural version of child is children, so childrens
is a linguistic error.
5.6.2
to 5.7.0
.This version is covered by your current version range and after updating it in your project the build failed.
@nestjs/core is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
@Get([])
, @Post([])
, etc) #1343There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
Not an issue but I have a suggestion.
Since this library is part of Nestjs core, It would be great to have a feature allowing us to just define our method in controllers without having the @get(), @post parts of the stuff.
Then we'll have a separate route file leveraging this library.
The route file would have a structure like this:
const routes: Routes = [
{
path: '/my-awesome-route',
// Here we have a syntax "ControllerClass:MethodToCallInController"
controller: 'MyAwesomeRouteController:getSomeAwesomeThing',
method: 'GET'
}
]
My controller would then go like this:
// Maybe this @Controller could also be get rid of when this feature got implemented
@Controller()
export class MyAwesomeRouteController {
constructor() { }
async getSomeAwesomeThing(): Promise<AwesomeThing> {
return { "data": "some awesome things" }
}
}
Thank you so much for all you're doing to improve our DX.
Really excited to see this project. Started using it right away and was pleased to see how easy it works out of the box. However I'm trying to build nested routes that are two (possibly more) levels deep.
const routes: Routes = [
{
path: '/myPath',
children: [
{path: '', module: MyApiModule}
]
}
]
MyApiModule has its own nested routes
const routes: Routes = [
{
path: '/v1',
children: [
{path: '/summary', module: SummaryModule}
]
}
]
When I try to hit /api/myPath/v1/summary
I get a 404 however when I hit /api/v1/summary
I get the response I'm expecting. I would expect that having a child module that also has children would flatten this way.
Hello,
it might be interesting to add names to each route, to use the name in the controllers and not a path.
So we could easily change a route without having to go into the controller.
In module:
const routes: Routes = [
{
path: '/api',
name: 'api',
children: [
{
path: '/cats',
module: CatsModule,
name: 'cats',
},
{
path: '/cats/:id',
module: CatsModule,
name: 'catsById',
},
{
path: '/dogs',
module: DogsModule,
name: 'dogs',
},
],
},
];
In controller:
// ...
@Controller()
export class CatsController {
private cats: string[] = [];
@Get('cats')
sayHello() {
return `Hello From CatsController`;
}
@Get('catsById')
getCat(@Param('catId') id: string) {
const idx = parseInt(id, 10) || 0;
return { cat: this.cats[idx - 1] || null };
}
5.7.2
to 5.7.3
.This version is covered by your current version range and after updating it in your project the build failed.
@nestjs/core is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.