UNPKG

27 kBMarkdownView Raw
1# OvernightJS
2
3:warning: __OvernightJS/logger is deprecated. Please use its offshoot jet-logger.__
4
5> TypeScript decorators for the ExpressJS Web Server!
6
7<img alt='overnightjs' src='https://github.com/seanpmaxwell/overnight/raw/master/overnightjs.png' border='0'>
8
9<a href="https://www.npmjs.com/package/@overnightjs/core" target="_blank"><img src="https://img.shields.io/npm/v/@overnightjs/core.svg" alt="NPM Version" /></a>
10<a href="https://www.npmjs.com/package/@overnightjs/core" target="_blank"><img src="https://img.shields.io/npm/l/@overnightjs/core.svg" alt="Package License" /></a>
11<a href="https://www.npmjs.com/package/@overnightjs/core" target="_blank"><img src="https://img.shields.io/npm/dm/@overnightjs/core.svg" alt="NPM Downloads" /></a>
12
13
14## What is it
15OvernightJS is a simple library to add TypeScript decorators for methods meant to call Express routes.
16It also includes a package for managing json-web-tokens and printing logs.
17
18
19## Features
20* Define a base route using a @Controller decorator.
21* Decorators to convert class methods to Express routes (@Get, @Put, @Post, @Delete etc).
22* Method decorators also work with arrow functions set as class properties.
23* @Middleware and @ClassMiddleware decorators.
24* @ErrorMiddleware and @ErrorMiddleware decorators to handle request errors.
25* Add options to controllers the same as you would Express routers with @ClassOptions.
26* Support for child-controllers with @ChildControllers.
27* @Wrapper and @ClassWrapper decorators to wrap functions.
28* Server superclass to initialize ExpressJS server and setup controllers.
29* Allows for adding your own custom Router classes if you don't want to use the standard express Router.
30* Easy to configure logging tool.
31* Json-Web-Token management.
32* Master repo includes a sample application, if you want to practice with an API calling tool such as Postman.
33* Compatible with both es5 and es6.
34* Fully type safe :)
35
36
37## Why OvernightJS
38OvernightJS isn't meant to be a replacement for Express. If you're already somewhat familiar with ExpressJS, you can
39learn Overnight in about 10 minutes. There are some other frameworks which do add decorators for Express such as NestJS
40and TsExpressDecorators, but these are massive frameworks with entire websites dedicated to their documentation. OvernightJS
41is clean, simple, and aside from the decorators, you can interact with ExpressJS in the same way you would any other Node
42application.
43
44
45## Table of Contents
46* [OvernightJS/core](#overnight-core)
47* [OvernightJS/logger](#overnight-logger)
48* [OvernightJS/jwt](#overnight-jwt)
49
50
51
52## Installation
53You can get the latest release using npm:
54
55```batch
56$ npm install --save @overnightjs/core express
57$ npm install --save-dev @types/express
58```
59
60> **Important!** OvernightJS requires Node >= 6, Express >= 4, TypeScript >= 2.0 and the `experimentalDecorators`,
61`lib` compilation options in your `tsconfig.json` file.
62
63
64## <a name="overnight-core"></a> Quick start
65
66#### Create your controller
67
68````typescript
69import { OK, BAD_REQUEST } from 'http-status-codes';
70import { Controller, Middleware, Get, Post, Put, Delete } from '@overnightjs/core';
71import { Request, Response } from 'express';
72import { Logger } from '@overnightjs/logger';
73
74@Controller('api/users')
75export class UserController {
76
77 @Get(':id')
78 private get(req: Request, res: Response) {
79 Logger.Info(req.params.id);
80 return res.status(OK).json({
81 message: 'get_called',
82 });
83 }
84
85 @Get('')
86 @Middleware([middleware1, middleware2])
87 private getAll(req: ISecureRequest, res: Response) {
88 Logger.Info(req.payload, true);
89 return res.status(OK).json({
90 message: 'get_all_called',
91 });
92 }
93
94 @Post()
95 private add(req: Request, res: Response) {
96 Logger.Info(req.body, true);
97 return res.status(OK).json({
98 message: 'add_called',
99 });
100 }
101
102 @Put('update-user')
103 private update(req: Request, res: Response) {
104 Logger.Info(req.body);
105 return res.status(OK).json({
106 message: 'update_called',
107 });
108 }
109
110 @Delete('delete/:id')
111 private delete(req: Request, res: Response) {
112 Logger.Info(req.params, true);
113 return res.status(OK).json({
114 message: 'delete_called',
115 });
116 }
117
118 @Get(/ane/) // Rexes supported. Matches /lane, /cane, etc.
119 public getAne(req: Request, res: Response): any {
120 return res.status(OK).json({
121 message: '/ane/',
122 });
123 }
124
125 @Get('practice/async')
126 private async getWithAsync(req: Request, res: Response) {
127 try {
128 const asyncMsg = await this.asyncMethod(req);
129 return res.status(OK).json({
130 message: asyncMsg,
131 });
132 } catch (err) {
133 Logger.Err(err, true);
134 return res.status(BAD_REQUEST).json({
135 error: err.message,
136 });
137 }
138 }
139
140 private asyncMethod(req: Request): Promise<string> {
141 return new Promise((resolve) => {
142 resolve(req.originalUrl + ' called');
143 });
144 }
145}
146````
147
148- You don't have to use class methods, you can also use class properties whose value is an arrow function. You will
149 have to cast Overnight to the 'any' type to avoid type errors though.
150
151````typescript
152import * as OvernightJS from '@overnightjs/core';
153
154 ...
155
156 @(OvernightJS as any).Get('arrow/:id')
157 private get = (req: Request, res: Response) => {
158 this.logger.info(req.params.id);
159 return res.status(200).json({msg: 'get_arrow_called'});
160 }
161````
162
163- If you want your middleware to apply to every route in a class use the `@ClassMiddleware` decorator.
164
165````typescript
166import { Controller, ClassMiddleware } from '@overnightjs/core';
167
168@Controller('api/users')
169@ClassMiddleware([middleware1, middleware2])
170export class UserController {
171
172 ...
173}
174````
175
176- You can set the `@ErrorMiddleware` / `@ClassErrorMiddleware` decorators to use [Express error handling](https://expressjs.com/en/guide/error-handling.html).
177
178````typescript
179import { Controller, ErrorMiddleware, ClassErrorMiddleware } from '@overnightjs/core';
180
181@Controller('api/users')
182@ClassErrorMiddleware(errorMiddleware1)
183export class UserController {
184
185 @Get(':id')
186 @ErrorMiddleware(errorMiddleware2)
187 private get(req: Request, res: Response)
188 ...
189}
190````
191
192- Child-controllers can be added with the `@ChildControllers` decorator. There's no limit to how
193many levels of nesting you can add. Make sure to instantiate them before adding them. Options at the
194class level can be added with `@ClassOptions` decorator.
195
196````typescript
197import { Controller, ClassOptions, ChildControllers } from '@overnightjs/core';
198import { ChildController1, ChildController2 } from '...'
199
200@Controller('api/users')
201@ClassOptions({mergeParams: true})
202@ChildControllers([
203 new ChildController1(),
204 new ChildController2(),
205])
206export class ParentController {
207
208 ...
209}
210````
211
212- You can wrap each class method in a custom function with the `@Wrapper` decorator. If you use the `@ClassWrapper`
213decorator then every method in that class will be wrapped with the provided method.
214
215````typescript
216import * as expressAsyncHandler from 'express-async-handler';
217import { ClassWrapper, Controller, Get, Wrapper } from '@overnightjs/core';
218import { Request, Response } from 'express';
219
220@Controller('wrapper-practice')
221// Or instead of using @Wrapper below you could use @ClassWrapper here
222export class WrapperController {
223
224 @Get('async-third-party/:id')
225 @Wrapper(expressAsyncHandler)
226 private async asyncThirdParty(req: Request, res: Response) {
227 const asyncMsg = await someAsyncFunction();
228 return res.status(200).json({
229 message: asyncMsg,
230 });
231 }
232}
233````
234
235#### Import your controllers into the server
236OvernightJS provides a Server superclass which initializes a new ExpressJS application. The express
237object is accessed using `this.app`, which is a protected, readonly class variable. You can interact
238with this variable like you would any normal express Application created with `require('express')()`.
239If you want to print to the console the name of each controller that has been successfully configured,
240set `showLogs` to `true` via the `this.showLogs` setter or the Server `constructor()`.
241<br>
242
243`super.addControllers()` must be called to enable all of the routes in your controller. Make sure to
244call it after setting up your middleware. You can pass `super.addControllers()` a single controller-instance
245or an array of controller-instances, but they must be instantiated first.
246<br>
247
248````typescript
249import * as bodyParser from 'body-parser';
250import { Server } from '@overnightjs/core';
251import { Logger } from '@overnightjs/logger';
252import { UserController } from './UserController';
253import { SignupController } from './SignupController';
254
255export class SampleServer extends Server {
256
257 constructor() {
258 super(process.env.NODE_ENV === 'development'); // setting showLogs to true
259 this.app.use(bodyParser.json());
260 this.app.use(bodyParser.urlencoded({extended: true}));
261 this.setupControllers();
262 }
263
264 private setupControllers(): void {
265 const userController = new UserController();
266 const signupController = new SignupController();
267 const dbConnObj = new SomeDbConnClass('credentials');
268 signupController.setDbConn(dbConnObj);
269 userController.setDbConn(dbConnObj);
270 // super.addControllers() must be called, and can be passed a single controller or an array of
271 // controllers. Optional router object can also be passed as second argument.
272 super.addControllers(
273 [userController, signupController],
274 /*, optional router here*/,
275 /* middleware that will apply to all controllers here */,
276 );
277 }
278
279 public start(port: number): void {
280 this.app.listen(port, () => {
281 Logger.Imp('Server listening on port: ' + port);
282 })
283 }
284}
285````
286
287**IMPORTANT NOTE:** If you initialize environment variables from some script which imports the
288Server script, those environment variables must be configured before importing the Server script
289or else they could end up undefined for nested controllers.
290
291#### See how awesome this is!
292Without the above decorators we would have to wrap each controller method with something like:
293
294````typescript
295/* In the controller file*/
296class UserController {
297
298 public getRoutes(): Router {
299 const router = Router();
300 router.get('/', [your middleware], (req, res) => {
301 // Do some stuff in here
302 });
303 router.get('/anotherRoute', [other middleware], (req, res) => {
304 // Do some stuff in here
305 });
306 // Repeat for every single controller method
307 return router;
308 }
309}
310
311let userController = new UserController();
312this.app.use('/api/users', userController.getRoutes());
313// Repeat for every single controller class
314````
315
316This would get really tedious overtime and lead to a lot of boiler plate code.
317
318
319#### <a name="custom-router"></a> Using a Custom Router
320Suppose you don't want to use the built in "Router" object which is provided by Express. Maybe you
321want use _express-promise-router_ because you don't like using `try/catch` blocks. OvernightJS allows
322you to pass in a custom router object in the `super.addControllers()` method. Simply pass in your
323custom router as the second param after the controller-instance/s. When you don't specify a custom
324router, the default express.Router() object is used.
325
326
327- Controller using _express-promise-router_:
328
329````typescript
330import { Request, Response } from 'express';
331import { Controller, Get } from '@overnightjs/core';
332
333@Controller('api/posts')
334export class PostController {
335
336 @Get(':id')
337 private get(req: Request, res: Response) {
338 return this.someAsyncFunction(req.params.id)
339 .then(ret => res.status(200).json({msg: ret}));
340 }
341
342 private someAsyncFunction(id: number): Promise<string> {
343 return new Promise((res, rej) => {
344 isNaN(id) ? rej('Invalid id') : res('Valid id');
345 })
346 }
347}
348````
349
350- Add _express-promise-router_ in the `super.addControllers()` method:
351
352````typescript
353import * as customRouter from 'express-promise-router';
354import { Server } from '@overnightjs/core';
355import { PostController } from './controllers/PostController';
356
357export class CustomRouterServer extends Server {
358
359 constructor() {
360 super();
361 super.addControllers(new PostController(), customRouter); // <-- custom router added here
362 }
363
364 ...
365}
366````
367<br>
368<br>
369<br>
370
371
372
373## <a name="overnight-logger"></a> OvernightJS/logger
374Despite the abundance of logging tools out there, knowing exactly which is the right one for your
375web-server might take more time than you feel like spending. So you can start logging events right
376away, OvernightJS comes with its own logging package. From the environment variables you can easily
377switch your logs to be printed out to the command line, a file, sent through your own custom logging
378logic, or turned off completely. Logs printed to the console also are printed out in different colors
379depending on whether they're info, a warning, an error, etc. The file for holding logs can be specified
380 manually or left as the default. Let's check it out!<br>
381
382### Installation
383```batch
384$ npm install --save @overnightjs/logger
385```
386
387### Guide
388The logger package's main export is the `Logger` class. Logger can used statically or as an instance
389with settings configured through a constructor.
390
391- The three environment variables are:
392 - `OVERNIGHT_LOGGER_MODE`: can be `'CONSOLE'`(default), `'FILE'`, `'CUSTOM'`, and `'OFF'`.
393 - `OVERNIGHT_LOGGER_FILEPATH`: the file-path for file mode. Default is _home_dir/overnight.log_.
394 - `OVERNIGHT_LOGGER_RM_TIMESTAMP`: removes the timestamp next to each log. Can be `'TRUE'` or `'FALSE'`(default).
395
396_logger_ has an export `LoggerModes` which is an enum that provides all the modes if you want to
397use them in code. I would recommend using `Console` for local development, `File` for remote development,
398and `Custom` or `Off` for production. If you want to change the settings in code, you can do so via
399the constructor or getters/setters.
400<br>
401
402
403- There are 4 functions on Logger to print logs. Each has a static counterpart:
404 - `info` or `Info`: prints green.
405 - `imp` or `Imp`: prints magenta.
406 - `warn` or `Warn`: prints yellow.
407 - `err` or `Err`: prints red.
408
409There is an optional second param to each method which is a `boolean`. If you pass `true` as the second
410param, Logger will use node's `util` so that the full object gets printed. You should NOT normally
411use this param, but it is especially useful when debugging errors so that you can print out the full
412error object and observe the stack trace.<br>
413
414Let's look at a code sample which sets the environment variables via a start script:
415
416- In the start script
417````typescript
418import * as path from 'path';
419import * as fs from 'fs';
420import { LoggerModes } from '@overnightjs/logger';
421
422// Set the
423const logFilePath = path.join(__dirname, '../sampleProject.log');
424process.env.OVERNIGHT_LOGGER_MODE = LoggerModes.File; // Can also be Console, Custom, or Off
425process.env.OVERNIGHT_LOGGER_FILEPATH = logFilePath;
426
427// Remove current log file if it exists
428(function removeFile() {
429 try {
430 fs.unlinkSync(logFilePath);
431 } catch (e) { return; }
432})();
433````
434
435- In the controller file
436````typescript
437import { OK } from 'http-status-codes';
438import { Request, Response } from 'express';
439import { Controller, Get } from '@overnightjs/core';
440import { Logger } from '@overnightjs/logger';
441
442@Controller('api/logger')
443export class LoggerPracticeController {
444
445 private readonly logger: Logger;
446
447 constructor() {
448 this.logger = new Logger();
449 }
450
451 @Get('static/console/:msg')
452 private printLogsConsole(req: Request, res: Response) {
453 Logger.Info(req.params.msg);
454 Logger.Imp(req.params.msg);
455 Logger.Warn(req.params.msg);
456 Logger.Err(req.params.msg);
457 Logger.Err(new Error('printing out an error'));
458 Logger.Err(new Error('printing out an error full'), true); // <-- print the full Error object
459 return res.status(OK).json({
460 message: 'static_console_mode',
461 });
462 }
463
464 @Get('console/:msg')
465 private printLogsConsole(req: Request, res: Response) {
466 this.logger.info(req.params.msg);
467 this.logger.imp(req.params.msg);
468 this.logger.warn(req.params.msg);
469 this.logger.err(req.params.msg);
470 this.logger.err(new Error('printing out an error'));
471 this.logger.err(new Error('printing out an error full'), true);
472 return res.status(OK).json({
473 message: 'console_mode',
474 });
475 }
476}
477````
478
479- The previous code-snippet will show the following content when printed to a file:
480````
481IMPORTANT: [2019-04-07T19:17:28.799Z]: OvernightJS with standard express router started on port: 3000
482INFO: [2019-04-07T19:18:08.939Z]: hello-logger
483IMPORTANT: [2019-04-07T19:18:08.939Z]: hello-logger
484WARNING: [2019-04-07T19:18:08.939Z]: hello-logger
485ERROR: [2019-04-07T19:18:08.940Z]: hello-logger
486ERROR: [2019-04-07T19:18:08.940Z]: Error: printing out an error
487ERROR: [2019-04-07T19:18:08.956Z]: Error: printing out an error full
488 at class_1.LoggerPracticeController.printLogsFile (/home/seanmaxwell/WebstormProjects/Overnight/sample-project/src/controllers/LoggerPracticeController.ts:49:20)
489 at class_1.descriptor.value [as printLogsFile] (/home/seanmaxwell/WebstormProjects/Overnight/src/core/lib/PropertyDecorators.ts:36:35)
490 at callBack (/home/seanmaxwell/WebstormProjects/Overnight/src/core/lib/Server.ts:78:50)
491 at Layer.handle [as handle_request] (/home/seanmaxwell/WebstormProjects/Overnight/src/core/node_modules/express/lib/router/layer.js:95:5)
492 at next (/home/seanmaxwell/WebstormProjects/Overnight/src/core/node_modules/express/lib/router/route.js:137:13)
493 at Route.dispatch (/home/seanmaxwell/WebstormProjects/Overnight/src/core/node_modules/express/lib/router/route.js:112:3)
494 at Layer.handle [as handle_request] (/home/seanmaxwell/WebstormProjects/Overnight/src/core/node_modules/express/lib/router/layer.js:95:5)
495 at /home/seanmaxwell/WebstormProjects/Overnight/src/core/node_modules/express/lib/router/index.js:281:22
496 at param (/home/seanmaxwell/WebstormProjects/Overnight/src/core/node_modules/express/lib/router/index.js:354:14)
497 at param (/home/seanmaxwell/WebstormProjects/Overnight/src/core/node_modules/express/lib/router/index.js:365:14)
498 at Function.process_params (/home/seanmaxwell/WebstormProjects/Overnight/src/core/node_modules/express/lib/router/index.js:410:3)
499 at next (/home/seanmaxwell/WebstormProjects/Overnight/src/core/node_modules/express/lib/router/index.js:275:10)
500 at Function.handle (/home/seanmaxwell/WebstormProjects/Overnight/src/core/node_modules/express/lib/router/index.js:174:3)
501 at router (/home/seanmaxwell/WebstormProjects/Overnight/src/core/node_modules/express/lib/router/index.js:47:12)
502 at Layer.handle [as handle_request] (/home/seanmaxwell/WebstormProjects/Overnight/src/core/node_modules/express/lib/router/layer.js:95:5)
503 at trim_prefix (/home/seanmaxwell/WebstormProjects/Overnight/src/core/node_modules/express/lib/router/index.js:317:13)
504````
505
506
507- And this when printed to the console:
508<img alt='overnightjs' src='https://github.com/seanpmaxwell/overnight/raw/master/loggerConsole.png' border='0'>
509
510
511### Using a custom logger
512For production you'll probably have some third party logging tool like ElasticSearch or Splunk. _logger_ exports
513one interface `ICustomLogger` which has one method `sendLog()` that needs to implemented. If you created a class
514which implements this interface, and add it to Logger through a setter or the constructor, and set the mode to `CUSTOM`,
515Logger will call whatever logic you created for `sendLog()`.
516
517````typescript
518// CustomLoggerTool.ts
519import { ICustomLogger } from '@overnightjs/logger';
520
521export class CustomLoggerTool implements ICustomLogger {
522
523 private readonly thirdPartyLoggingApplication: ThirdPartyLoggingApplication;
524
525 constructor() {
526 this.thirdPartyLoggingApplication = new ThirdPartyLoggingApplication();
527 }
528
529 // Needs to be implemented
530 public sendLog(content: any, prefix: string): void {
531 // prefix is either: INFO | ERROR | WARNING | IMPORTANT
532 this.thirdPartyLoggingApplication.doStuff(content);
533 }
534}
535````
536
537````typescript
538 // In the controller file
539
540 ...
541
542 @Get('useCustomLogger/:msg')
543 private useCustomLogger(req: Request, res: Response) {
544 const logger = new Logger(LoggerModes.CUSTOM, '', true, this.customLoggerTool);
545 logger.rmTimestamp = true;
546 logger.info(req.params.msg);
547 return res.status(OK).json({
548 message: 'console_mode',
549 });
550 }
551````
552<br>
553<br>
554<br>
555
556
557
558## <a name="overnight-jwt"></a> OvernightJS/jwt
559
560### What is it
561This is an easy tool for removing boilerplate code around json-web-tokens (jwt). You can get your token
562and middleware with just one line of code. @overnightjs/core is a sister library to add TypeScript decorators
563for methods meant to call Express routes and is not required for @overnightjs/jwt but they do work beautifully
564together.
565
566
567### Features
568* `JwtManager` class which, when when used statically, can pull the JWT expiration and secret from
569the environment variables.
570* When used as an instance-object, `JwtManager` can be dynamically passed the JWT expiration and secret
571if you prefer to set them through the code.
572* Default values for the secret and expiration when used statically. This is convenient for a
573development environment.
574* Fully type-safe :)
575
576
577### Installation
578```batch
579$ npm install --save @overnightjs/jwt express
580$ npm install --save-dev @types/express @types/express-jwt @types/jsonwebtoken
581```
582
583### Table of Contents
584* [Option 1](#option-1)
585* [Option 2](#option-2)
586
587
588#### <a name="options-1"></a> Option 1: Environment Variables
589This is what really saves you from having to do boilerplate code. The two environment variables you
590need to set are **OVERNIGHT_JWT_SECRET** and **OVERNIGHT_JWT_EXP**. OVERNIGHT_JWT_SECRET should be a really
591long, random string (recommended is 80 characters) and the rules for setting OVERNIGHT_JWT_EXP are the same as
592setting the expiration time for the _jsonwebtoken_ library. The rules are:
593
594> If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds is used by
595default ("120" is equal to "120ms"). Examples: "2 days", "10h", "7d".
596
597How you set your environment variables will vary depending on the which environment you are working in.
598I use Ubuntu which is pretty easy. Just open the _/etc/environment_ file and type:
599
600> OVERNIGHT_JWT_SECRET="your super long random string" <br>
601> OVERNIGHT_JWT_EXP="your expiration time"
602
603Another common option is the `dotenv` library, which imports environment variables from a _.env_ file
604<br>
605
606If you do not set these environment variables, a default value of **'3 days'** will be set for the expiration time and a
607random string will be generated for the secret. The random string is fine for development but do not use it for
608production. Every time you restart the server the secret will change and all client-side JWTs will become invalid.
609<br>
610
611Now let's create the controller. The data that is encrypted is stored as the `payload` property. That's all there is to it.
612Just import `JwtManager`.
613
614
615````typescript
616import { OK } from 'http-status-codes';
617import { JwtManager, ISecureRequest } from '@overnightjs/jwt';
618import { Controller, Middleware, Get, Post } from '@overnightjs/core';
619import { Request, Response } from 'express';
620
621@Controller('api/jwt')
622export class JwtPracticeController {
623
624 @Get(':email')
625 private getJwt(req: Request, res: Response) {
626 const jwtStr = JwtManager.jwt({
627 email: req.params.email
628 });
629 return res.status(OK).json({
630 jwt: jwtStr,
631 });
632 }
633
634 @Post('callProtectedRoute')
635 @Middleware(JwtManager.middleware)
636 private callProtectedRoute(req: ISecureRequest, res: Response) {
637 return res.status(OK).json({
638 email: req.payload.email,
639 });
640 }
641}
642````
643
644#### <a name="options-2"></a> Option 2: Pass through the constructor
645If you want to set your secret and expiration time manually, you can instantiate the `JwtManager` class
646and set them via the constructor. I love using Option 1 way more, but I thought I'd supply this option
647for people who prefer to import it another way.
648
649````typescript
650import { OK } from 'http-status-codes';
651import { JwtManager, ISecureRequest } from '@overnightjs/jwt';
652import { Controller, Middleware, Get, Post } from '@overnightjs/core';
653import { Request, Response } from 'express';
654
655const jwtMgr = new JwtManager('secret', '10h');
656
657@Controller('api/jwt')
658export class JwtPracticeController {
659
660 @Get('getJwtAlt/:fullname')
661 private getJwtFromHandler(req: Request, res: Response) {
662 const jwtStr = jwtMgr.jwt({
663 fullName: req.params.fullname
664 });
665 return res.status(OK).json({
666 jwt: jwtStr,
667 });
668 }
669
670 @Post('callProtectedRouteAlt')
671 @Middleware(jwtMgr.middleware)
672 private callProtectedRouteFromHandler(req: ISecureRequest, res: Response) {
673 return res.status(OK).json({
674 fullname: req.payload.fullName,
675 });
676 }
677}
678````
679
680
681#### Works just as fine in regular Express
682You dont have to use `@overnightjs/jwt` with `@overnightjs/core`. If you're using Express but are not
683interested in using decorators, you can pass the middleware just the same as you would for any typical
684Express Router object.
685
686````javascript
687const router = express.Router();
688
689router.get('users', JwtManager.middleware, (req, res) => {
690 console.log(req.payload.email);
691})
692
693app.use('/', router);
694````
695
696
697## That's All!!
698Please star this repo if you found it useful. Happy web-deving :)
699
700
701## License
702[MIT](LICENSE)
703
\No newline at end of file