内容简介:A productionWe started working with NestJS few months back, we were blown away with the functionalities that it provides
NestJS Boilerplate
A production
Table of Content
Introduction
We started working with NestJS few months back, we were blown away with the functionalities that it provides
This boilerplate helps avoid the redundancy cycle each developer has to go through, it handles most of the repetitive
Getting Started
If you using Github GUI
Git CLI
# head to your workspace 1. cd to/your/favourite/directory/on/the/system # clone the template 2. git clone https://github.com/squareboat/nestjs-boilerplate your-project # go to the directory where the clone happened 3. cd your-project # let's set some environment variables 4. cp .env.example .env 5. vi/nano .env # now, let's install the dependencies 6. npm install # start the server in watch mode 7. npm run start:dev # Boom :boom: and it is done!
Optional Step:When you cloned the repo, the git commit history also got cloned, to clean/erase the history
# remove the .git directory from the project folder 1. rm -rf .git # initialize a new repo on the same content 2. git init # add the content to stage 3. git add . # do your first commit 4. git commit -m ':rocket: INITIAL COMMIT' # add origin url 5. git remote add origin git@github.com:<YOUR ACCOUNT>/<YOUR REPOS>.git # do your firt push 6. git push -u origin master
NPM Commands
This boilerplate contains following npm commands (apart from NestJS' one) to support you from the day one of your sprint. Yeah! We love to help
# Create a new db migration npm run migration:create # Runs all the pending migrations :sunglasses: npm run migration:up # Helps revert the db changes when you need to :wink: npm run migration:down
Batteries
We have added some small and big batteries
Configuration
Request Helpers
-
all()
: Method to get the incoming parameters, all at once. No need to getbody
,queryParams
, andparams
seperately every time.
const inputs = req.all();
Response Helpers
We have our own very generous set of api guidelines, we used our learning of multiple projects to provide structural consistency of response object (which is often unknowningly abused).
-
success(data: Record<string, any>, status=200)
: Returns the success response, use this whenever your request is succesfull, usually for GET and POST requests.
/** * { * success: true, * code: 200, * data: { message: "Hello There" } * }; **/ return res.success({ message: 'Hello there!' });
-
error(error: Record<string, any> | string, status = 401)
: Returns the error response, used in exception filter.
/** * { * success: false, * code: 401, * message: 'Unauthorized' * }; **/ return res.error('Unauthorized!');
-
noContent()
: There are cases when we need to send only a success status code and no body.noContent()
will come in handy for you.
// will return a response with status code of 204 return res.noContent();
-
withMeta(data: Record<string, any>, status = 200)
: There can be some case where we need to send some payload to support our requested data. For example, pagination information incase of a paginated response.withMeta
helps you achieve the same.
/** * { * success: true, * code: 200, * data:[{},{},{}] * meta: { * pagination: { * totalPages: 10, * currentPage: 2, * }, * ...some other custom attributes * } * }; **/ return res.withMeta({ data: [{}, {}], pagination: { totalPages: 10, currentPage: 2 }, });
Exception Handling
NestJS provides option of writing your own exception filters. We have added an exception filter with all the necessary exceptions to help you get started on the project very quickly.
No configuration is needed on your side. It is already added as a Global filter.
Helpers
Think of this as a randomly used stateless functions which can be used anywhere and anytime. We have included a bunch of "helper" functions. Many of them are used inside the template, you are free to use it at your convenience.
-
uuid(): string
: Generate and returns a v4 uuid string. -
randomNumber(n: number): string
- Takesn
param as length and returns a random numeric string. -
httpBuildQuery(url: string, params = {})
- Takesurl
andparams
object, and returns a url with query string attached.
/** * https://example.com?q=some%20search%20term */ httpBuildQuery('https://example.com', { q: 'some search term' });
-
basePath()
: Get the root/base path of the project, irrespective of the directory that you are in.
You may want to add your helper function, you can do so by adding it to /src/core/helpers/index.ts
file
Transformers
Transformer provides a presentation and transformation layer for complex data output, for example JSON response in REST APIs. Let's see any example on how it works.
Supports only JSON response for now.
We have already added a base Transformer
class inside the core
module, the driver of our logic.
- Let's create a
BookTransformer
for a model, sayBook
.
// src/transformers/book.ts import { Transformer } from '@app/core'; export class BookTransformer extends Transformer { async transform(book: Record<string, any>): Promise<Record<string, any>> { return { id: book.uuid, name: book.name, publisherName: book.publisher, publishedOn: moment(book.publishedAt).format('YYYY-MM-DD'), }; } }
Now to use the transformer, follow the steps below:
//TheFileWhereYouWantToUseIt.ts import { BookTransformer } from '@app/transformers/book'; const transformer = new BookTransformer(); const payload = await transformer.work({ uuid: '75442486-0878-440c-9db1-a7006c25a39f', name: "NestJS Boilerplate", publisher: 'Squareboat' publishedAt: "2020-12-03 22:00:00", }); /** * { * id: "75442486-0878-440c-9db1-a7006c25a39f", * name: "NestJS BoilerPlate", * publisherName: "Squareboat", * publishedAt: '2020-12-03' * } */ console.log(payload)
Wait , transformer provide much more than a wrapper class. While creating REST APIs you may come across a case where you want to fetch some related data with the main data.
For example, you may want to fetch author details along with the details of the book's detail that you requested.
Transformer provides an option to add all the available includes and default includes a transformer.
// src/transformers/book.ts import { Transformer } from '@app/core'; export class BookTransformer extends Transformer { availableIncludes = ['author']; defaultIncludes = []; async transform(book: Record<string, any>): Promise<Record<string, any>> { return { id: book.uuid, name: book.name, publisherName: book.publisher, publishedOn: moment(book.publishedAt).format('YYYY-MM-DD'), }; } async includeAuthor(book: Record<string, any>): Promise<Record<string, any>> { // fetch author of the book const author = book.author; return this.item(book.author, new AuthorTransformer()); } }
Notice the "author" inside the availableIncludes
and includeAuthor
method, transformer will add include namespace to the requested include.
AuthorTransformer is just like BookTransformer, but responsible for transformer author model.
Now to use the include the author
option, we need to pass the include
queryParam in the URL, like: /books/75442486-0878-440c-9db1-a7006c25a39f?include=author
For multiple includes, send comma seperated include options like include=author,publisher,releaseDetails
Now, inside your controller, do the following:
//BookController.ts import { Get} from '@nestjs/common'; import { BookTransformer } from '@app/transformers/book'; // inside the Books Controller @Get('/books/:uuid') async get(@Req() req: Request, @Res() res: Response): Promise<Response> { const inputs = req.all(); const transformer = new BookTransformer(); const payload = await transformer .parseIncludes(inputs.include) .work({ uuid: '75442486-0878-440c-9db1-a7006c25a39f', name: "NestJS Boilerplate", publisher: 'Squareboat' publishedAt: "2020-12-03 22:00:00", }); /** * { * id: "75442486-0878-440c-9db1-a7006c25a39f", * name: "NestJS BoilerPlate", * publisherName: "Squareboat", * publishedAt: '2020-12-03', * "author": {"id": "a1", "name": "Vinayak Sarawagi"} * } */ return res.success(payload); }
In the Controllers
topic, we will discuss how we have managed to automate these steps also.
Controllers
Developers coming from MVC will know what is a controller and how it helps us to handle the request and response lifecycle.
For elegant handling we have added a base ApiController
which has all the necessary functions to handle the response transformation.
-
transform(obj, transformer, options?)
: You might have noticed in the previous snippets, on how we created an instance of the transformer and ran the methods to process an output. To handle it more beautifully, you can handle it like below:
//BookController.ts import { Get} from '@nestjs/common'; import { BookTransformer } from '@app/transformers/book'; // inside the Books Controller @Get('/books/:uuid') async get(@Req() req: Request, @Res() res: Response): Promise<Response> { const inputs = req.all(); const book = { uuid: '75442486-0878-440c-9db1-a7006c25a39f', name: "NestJS Boilerplate", publisher: 'Squareboat' publishedAt: "2020-12-03 22:00:00", }; /** * Coding Pattern changed, output remains the same a above */ return res.success(await this.transform( book, new BookTransformer, {req} )) }
Notice, the {req}
object that we are passing as third param, the base ApiController
itself handles reading the url and parsing the includes. Now we don't need to do the tedious task again and again.
-
collection(obj, transformer, options?)
: Same responsibility as thetransform
method. Use this whenever you need to transform anarray
. -
paginate(obj, transformer, options?)
: Breaks down theobj
passed into transformed data and pagination data. Expects theobj
to includepagination
key.If you are dealing with some other key than
pagination
, you can change the key name insidepaginate
method in src/core/controllers/ApiController.ts file.
Validators
Repositories
Contributing
About Us
We are a bunch of dreamers, designers, and futurists. We are high on collaboration, low on ego, and take our happy hours seriously. We'd love to hear more about your product. Let's talk and turn your great ideas into something even greater! We have something in store for everyone.
License
The MIT License. Please see License File for more information. Copyright © 2020 SquareBoat.
Made with
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深入理解程序设计
[美] Jonathan Bartlett / 郭晴霞 / 人民邮电出版社 / 2014-1 / 49.00
是否真正理解汇编语言,常常是普通程序员和优秀程序员的分水岭。《深入理解程序设计:使用Linux汇编语言》介绍了Linux平台下的汇编语言编程,教你从计算机的角度看问题,从而了解汇编语言及计算机的工作方式,为成就自己的优秀程序员之梦夯实基础。 很多人都认为汇编语言晦涩难懂,但New Medio技术总监Jonathan Bartlett的这本书将改变人们的看法。本书首先介绍计算机的体系结构,然后......一起来看看 《深入理解程序设计》 这本书的介绍吧!
随机密码生成器
多种字符组合密码
Markdown 在线编辑器
Markdown 在线编辑器