-
-
Notifications
You must be signed in to change notification settings - Fork 37
docs: nestjs guide for v3 #526
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
Merged
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Submodule v3-doc-orm
updated
3 files
| +2,483 −2,483 | package-lock.json | |
| +2 −2 | package.json | |
| +4 −4 | zenstack/input.ts |
Submodule v3-doc-orm-computed-fields
updated
4 files
| +29 −29 | package-lock.json | |
| +2 −2 | package.json | |
| +4 −4 | zenstack/input.ts | |
| +9 −13 | zenstack/schema.ts |
Submodule v3-doc-orm-policy
updated
6 files
| +4 −4 | basic/zenstack/input.ts | |
| +9 −13 | basic/zenstack/schema.ts | |
| +35 −35 | package-lock.json | |
| +3 −3 | package.json | |
| +4 −4 | post-update/zenstack/input.ts | |
| +9 −13 | post-update/zenstack/schema.ts |
Submodule v3-doc-orm-polymorphism
updated
3 files
| +28 −28 | package-lock.json | |
| +2 −2 | package.json | |
| +7 −7 | zenstack/input.ts |
Submodule v3-doc-orm-typed-json
updated
4 files
| +1 −0 | filter.ts | |
| +2,482 −2,482 | package-lock.json | |
| +2 −2 | package.json | |
| +3 −3 | zenstack/input.ts |
Submodule v3-doc-orm-validation
updated
4 files
| +29 −29 | package-lock.json | |
| +2 −2 | package.json | |
| +3 −3 | zenstack/input.ts | |
| +11 −15 | zenstack/schema.ts |
Submodule v3-doc-quick-start
updated
4 files
| +29 −29 | package-lock.json | |
| +2 −2 | package.json | |
| +4 −4 | zenstack/input.ts | |
| +9 −13 | zenstack/schema.ts |
Submodule v3-doc-server-adapter
updated
4 files
| +41 −41 | package-lock.json | |
| +4 −4 | package.json | |
| +4 −4 | zenstack/input.ts | |
| +9 −13 | zenstack/schema.ts |
Submodule v3-doc-tanstack-query
updated
5 files
| +42 −42 | package-lock.json | |
| +4 −4 | package.json | |
| +4 −4 | src/zenstack/input.ts | |
| +9 −13 | src/zenstack/schema-lite.ts | |
| +9 −13 | src/zenstack/schema.ts |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| position: 1 | ||
| position: 2 | ||
| label: Databases | ||
| collapsible: true | ||
| collapsed: true | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,168 @@ | ||
| --- | ||
| sidebar_position: 4 | ||
| --- | ||
|
|
||
| # Using ZenStack With NestJS | ||
|
|
||
| This guide describes different ways to use ZenStack in a [NestJS](https://nestjs.com/) application. | ||
|
|
||
| ## As a Plain ORM | ||
|
|
||
| ZenStack offers a standard ORM component that you can use in your NestJS application just like any other ORM. To get started, create a `DbService` by extending the `ZenStackClient` constructor: | ||
|
|
||
| ```ts title="db.service.ts" | ||
| import { ZenStackClient } from '@zenstackhq/orm'; | ||
| import { PostgresDialect } from '@zenstackhq/orm/dialects/postgres'; | ||
| import { schema, type SchemaType } from './zenstack/schema'; | ||
| import { Pool } from 'pg'; | ||
|
|
||
| export class DbService extends ZenStackClient< | ||
| SchemaType, | ||
| ClientOptions<SchemaType> | ||
| > { | ||
| constructor() { | ||
| super(schema, { | ||
| dialect: new PostgresDialect({ | ||
| pool: new Pool({ connectionString: process.env.DATABASE_URL }) | ||
| }), | ||
| }); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| You can then register this service as a provider in a module: | ||
|
|
||
| ```ts title="app.module.ts" | ||
| import { Module } from '@nestjs/common'; | ||
| import { AppController } from './app.controller'; | ||
| import { DbService } from './db.service'; | ||
|
|
||
| @Module({ | ||
| controllers: [AppController], | ||
| providers: [DbService], | ||
| }) | ||
| ``` | ||
|
|
||
| Finally, inject the `DbService` in your controllers or other services to access the database: | ||
|
|
||
| ```ts title="app.controller.ts" | ||
| import { Controller, Get } from '@nestjs/common'; | ||
| import { DbService } from './db.service'; | ||
|
|
||
| @Controller('api') | ||
| export class AppController { | ||
| constructor(private readonly dbService: DbService) {} | ||
|
|
||
| @Get('/posts') | ||
| getPosts() { | ||
| return this.dbService.post.findMany(); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## As an Access-Controlled ORM | ||
|
|
||
| To leverage ZenStack's [built-in access control features](../orm/access-control/), you can inject a request-scoped `DbService` that's bound to the current session user (usually extracted from the request). | ||
|
|
||
| In the sample below, we provide an access-controlled `DbService` under the name "AUTH_DB": | ||
|
|
||
| ```ts title="app.module.ts" | ||
| import { Module, Scope } from '@nestjs/common'; | ||
| import { REQUEST } from '@nestjs/core'; | ||
| import type { Request } from 'express'; | ||
| import { PolicyPlugin } from '@zenstackhq/plugin-policy'; | ||
| import { DbService } from './db.service'; | ||
| // your authentication helper | ||
| import { getRequestUser } from './auth.util'; | ||
|
|
||
| @Module({ | ||
| controllers: [AppController], | ||
| providers: [ | ||
| // the standard (no-access-control) ORM | ||
| DbService, | ||
|
|
||
| // the access-controlled ORM | ||
| { | ||
| provide: 'AUTH_DB', | ||
|
|
||
| // make sure it's request-scoped to capture per-request user context | ||
| scope: Scope.REQUEST, | ||
|
|
||
| useFactory: (req: Request, db: DbService) => { | ||
| // extract the current user from the request, implementation depends on | ||
| // your authentication solution | ||
| const user = getRequestUser(req); | ||
|
|
||
| // install the PolicyPlugin and set the current user context | ||
| return db.$use(new PolicyPlugin()).$setAuth(user); | ||
| }, | ||
|
|
||
| inject: [REQUEST, DbService], | ||
| }, | ||
| ], | ||
| }) | ||
| ``` | ||
|
|
||
| Now you can choose to use the access-controlled `DbService` in your controllers or services by injecting it with the "AUTH_DB" token: | ||
|
|
||
| ```ts title="app.controller.ts" | ||
| import { Controller, Get, Inject } from '@nestjs/common'; | ||
| import { DbService } from './db.service'; | ||
|
|
||
| @Controller('api') | ||
| export class AppController { | ||
| // inject the access-controlled DbService | ||
| constructor(@Inject('AUTH_DB') private readonly dbService: DbService) {} | ||
|
|
||
| @Get('/posts') | ||
| getPosts() { | ||
| // only posts accessible to the current user will be returned | ||
| return this.dbService.post.findMany(); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## As an Automatic CRUD Service | ||
|
|
||
| ZenStack also provides [API handlers](../service/api-handler/) that process CRUD requests automatically for you. To use it, create a catch-all route in your controller and forward the request to the API handler: | ||
|
|
||
| ```ts title="app.controller.ts" | ||
| import { Controller, All, Inject, Param, Query, Req, Res } from '@nestjs/common'; | ||
| import type { Request, Response } from 'express'; | ||
| import { DbService } from './db.service'; | ||
|
|
||
| @Controller('api') | ||
| export class AppController { | ||
| // RESTful API Handler is used here for demonstration. You can also use the | ||
| // RPC-style API handler if preferred. See the API handlers docs for more | ||
| // details. | ||
| private readonly apiHandler = new RestApiHandler({ | ||
| schema, | ||
| endpoint: 'http://localhost:3000/api', | ||
| }); | ||
|
|
||
| constructor(@Inject('AUTH_DB') private readonly dbService: DbService) {} | ||
|
|
||
| @All('/*path') | ||
| async handleAll( | ||
| @Req() req: Request, | ||
| @Res() response: Response, | ||
| @Param('path') path: string[], | ||
| @Query() query: Record<string, any>, | ||
| ) { | ||
| // forward the request to the API handler | ||
| const result = await this.apiHandler.handleRequest({ | ||
| method: req.method, | ||
| path: path.join('/'), | ||
| query, | ||
| requestBody: req.body, | ||
| client: authDb, | ||
| }); | ||
|
|
||
| response.status(result.status).json(result.body); | ||
| } | ||
| } | ||
| ``` | ||
ymc9 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| With this setup, all requests to `/api/*` will be handled by the ZenStack API handler, which performs the necessary CRUD operations with access control enforced. Refer to the [API handlers documentation](../service/api-handler/) for request and response formats and other details. | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| --- | ||
| sidebar_position: 2 | ||
| sidebar_position: 3 | ||
| --- | ||
|
|
||
| # Working With PostgreSQL Schemas | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.