0.1.10 • Published 3 years ago

nextjs-decorators v0.1.10

Weekly downloads
-
License
MIT
Repository
github
Last release
3 years ago

a simple and lightweight collection of decorators to create APIs in an elegant way in DI pattern

Prerequisites

  • node >=10

Install

npm i nextjs-decorators

Usage

Step 1: Define a controller with @Controller decorator

//  pages/api/hello.ts

import { Controller } from 'nextjs-decorators'

@Controller('api/hello') // <--this should match with the route's url generated by Next.js
class MyAwesomeController {

}

Step 2: Defined a route with @{Method} decorator

//  pages/api/hello.ts

import { Controller, Get, Post, Param, Body } from 'nextjs-decorators'

@Controller('api/hello')                    
class MyAwesomeController {

    @Get(':id')                               // <-- this will match with route GET api/hello/{id}
    findById(@Param('id')id:string){          // <-- get the param from url
      return someDatabaseClient.findById(id)  // <-- Promise will be automatically resolved
    }
  
    @Post('')                              // <-- this will match with route POST api/hello
    findById(@Body()body: BodyInterface){     // <-- get the body from request       
      return someDatabaseClient.create(body)  // <-- Promise will be automatically resolved
    }

}

Step 3: Register the controller

  //  pages/api/hello
  import { Controller, Get, Post, Param, Body, registerController } from 'nextjs-decorators'

  @Controller('api/hello')                    
  class MyAwesomeController {

      @Get(':id')                               
      findById(@Param('id')id:string){          
        return someDatabaseClient.findById(id)  
      }
  
      @Post('')                               
      findById(@Body()body: BodyInterface){    
        return someDatabaseClient.create(body)  
      }

  }

  export default registerController(MyAwesomeController)  //  <--- all routes will be registered  

Dependency Injection(DI)

  // page/api/service.ts
  export class MyService{

      sayHello(){
        return { message: "you are awesome" }
      }    

  }


  // page/api/hello.ts
  import { Get, Controller, AutoInject, registerController } from 'nextjs-decorators' 
  import { MyService } from './service.ts';

  @AutoInject()             // <-- automatically inject list of dependencies in constructor
  @Controller('/api/hello')
  class MyAwesomeController{

      constructor(private service: MyService){}

      @Get()
      getMessage(){
        return this.service.sayHello()
      }

  }

  export default registerController(MyAwesomeController)

Middleware

Basic usage

// pages/api/hello.ts
import { UseMiddleware, Controller, Get, registerController } from 'nextjs-decorators'

@UseMiddleware((req, res) => {
  /** do something like logic stuffs */
  /** Middleware at class level will apply its logic to all route in class */
  console.log(`${new Date()} - IP: ${req.ip} URL: ${req.URL}`)
  })   
@Controller("api/hello")
class MyAwesomeController{

    @Get()
    @UseMiddleware(()=> {
      console.log("route middleware get executed")    
    })
    saySomethingObvious(){
      return { message: "you are awesome" }
    }
}

export default registerController(MyAwesomeController)

WARNING: return statement in middleware will return immediately to the client, for example

// pages/api/hello.ts
import { UseMiddleware, Controller, Get, registerController } from 'nextjs-decorators'

@Controller("api/hello")
class MyAwesomeController{

    @Get()
    @UseMiddleware(()=> {
      return { message: "return at middleware" }  // <-- this is the result which client will receive
    })
    saySomethingObvious(){
      return { message: "you are awesome" } // <-- in fact this will never get executed
    }
}

export default registerController(MyAwesomeController)

Guard

Guard is pretty much like Middleware, how ever it accept return type of boolean, if falsy value is returned it will throw an Unauthorize exception, and cannot access the desired route

// pages/api/hello.ts
import { UseGuard, Controller, Get, registerController, Request } from 'nextjs-decorators'
import { NextApiRequest } from 'next'

@UseGuard((req: Request)=> {
  const user = database.user.findOne({ id: req.query.id }) 
  req.user = user
  return user;// <- throw Unauthorize exception if user not found in database
})
@Controller("api/hello")
class MyAwesomeController{

    @Get()
    @UseGuard(()=> user.role !== 'admin' /** access the user from the request we've set above */)
    adminRoute(){
      return { message: "Hi admin" } 
    }
}

export default registerController(MyAwesomeController)

Author

šŸ‘¤ tienpvse(Phan Van Tien)

Show your support

Give a ā­ļø if this project helped you!

0.1.10

3 years ago

0.1.9

3 years ago

0.1.8

3 years ago

0.1.7

3 years ago

0.1.6

3 years ago

0.1.5

3 years ago

0.1.4

3 years ago

0.1.2

3 years ago

0.1.1

3 years ago

0.1.0

3 years ago