koa Routing Nursery Level Tutorial

# koa Routing Nursery Level Tutorial

Time: 11 September 2021

Author: Wu Yefei

---

In this series, I'll build projects from scratch to show you how to transform from the most basic routing writing to best practices. You'll see everything from writing all routes in app.js to pulling routes out, to routing auto-introduction and auto-registration.

#Project Setup

##Prepare

New Folder learn-koa-router

New file app.js

Initialize npm: `npm init`

Download koa:`npm install koa`

The project directory looks like this now

 

##Run the server first

// app.js

const Koa = require('koa')

const app = new Koa();

app.listen(3001)

console.log('listen 3001');

Basic Route Writing

Now instead of using koa-router, let's go back to the most basic routing

// app.js

const Koa = require('koa')

const app = new Koa();

app.use(async (ctx, next) => {

    if (ctx.path === '/hello/router' && ctx.method === 'GET') {

        ctx.body = {

            key: "hello world"

        }
    
    }

})

app.listen(3001)

console.log('listen 3001');

Execute `node app.js'in the terminal after writing, then go to the browser to access`http://localhost:3001/hello/router` (or use the postman request) to see that we have successfully returned

{"key":"hello world"}

##Use koa-router

As you can see, we can handle routes without using koa-router, but we have more logic to handle by ourselves, so in production environments we still choose to use good wheels. Here's how to use koa-router

Download koa-router: `npm install koa-router`

Overwrite`app.js`

// app.js

const Koa = require('koa')

const Router = require('koa-router')

const app = new Koa();

const router = new Router()

router.get('/hello/router', (ctx, next) => {

    ctx.body = {

        key: "hello koa-router"

    }

})

app.use(router.routes())

app.listen(3001)

console.log('listen 3001');

Execute `node app.js'in the terminal after writing, then go to the browser to access`http://localhost:3001/hello/router` (or use the postman request) to see that we have successfully returned

{"key":"hello koa-router"}

##Routing Split

In theory, we can now write all the routes we need in app.js, and the project can run, but that's not elegant. Routing is written entirely in app.js, which makes the file app.js bloated, difficult to maintain, and unreadable. So we'll consider making the routes specific to the project directory below.

 

Notice that we have two folders, v1 and v2. This is to allow for a distinction between the versions of the api and make it easy for new and old data to be compatible. Here v1 and V2 represent our api version number. About APIVersion distinction We have the opportunity to talk more carefully in the future. If we talk about routing split, we may not pay attention to this version distinction for the moment. Here, I build folders in accordance with the regular production environment, setting an ambush.

hello.js

// hello.js

const Router = require('koa-router')

const router = new Router();

router.get('/v1/hello/router', (ctx, next) => {

    ctx.body = {

        key: "hello koa-router v1"

    }

})

module.exports = router;

world.js

// world.js

const Router = require('koa-router')

const router = new Router();

router.get('/v1/world/router', (ctx, next) => {

    ctx.body = {

        key: "world v1"

    }

})

module.exports = router;

app.js

// app.js

const Koa = require('koa')

const hello = require('./app/api/v1/hello')

const world = require('./app/api/v1/world')

const app = new Koa();

app.use(hello.routes())

app.use(world.routes())

app.listen(3001)

console.log('listen 3001');

Execute `node app.js'in the terminal after writing, then go to the browser to access`http://localhost:3001/v1/hello/router` (or use the postman request) to see that we have successfully returned

{"key":"hello koa-router v1"}

As you can see here, what we are asking for is `http://localhost:3001/v1/hello/router`url has V1 added. This is how the api version is written in the url. In the same way, we can request `/v2/hello/router', `/v3/hello/router'in the future. I can't help but pull back to the api version and talk about routing.

After our pull-out, we have now achieved that each routing module is written in a special file, app.js only refers to and registers routes, which is much cleaner. But we can't stop there, there is still room for optimization.

Predictably, if we have hundreds of api s, we need to manually require one into app.js and manually register app.use. Too tired, programmers who don't want to be "lazy" aren't good programmers. We want programs to automatically import and register!

Automatic Import Routing and Registration

The principle of automatic import is very simple, it is to find all the files under `app/api/v1` and require into app.js. This logic can be written by itself, but we choose to use wheel `require-directory'.

Download require-directory:`npm install require-directory`

Overwrite app.js

// app.js

const Koa = require('koa')

const Router = require('koa-router')

const requireDirectory = require('require-directory')

const app = new Koa();

const apiDirectory = `${process.cwd()}/app/api` // Stitching Absolute Path

function whenLoadModule(obj) {

    if (obj instanceof Router) {

        app.use(obj.routes())

    }

}

requireDirectory(module, apiDirectory, {

    visit: whenLoadModule

})

app.listen(3001)

console.log('listen 3001');

Execute `node app.js'in the terminal after writing, then go to the browser to access`http://localhost:3001/v1/hello/router` (or use the postman request) to see that we have successfully returned

{"key":"hello koa-router v1"}

Explain the code here, requireDirectory uses three parameters, the first module can be simply understood as writing to death (you can go to the official website to see more about it)., the second apiDirectory is the folder path, which can be either relative or absolute. I spelled the absolute path here to make it easier to move code without changing the path in the future. The path here is the folder path where require is needed; the whenLoadModule in the third parameterMethod can be simply understood as a callback function. The requireDirectory method calls this callback function every time a module is introduced. The introduced module is passed into the callback function. Remember what our route says?

// app/api/v1/hello.js

const Router = require('koa-router')

const router = new Router();

router.get('/v1/hello/router', (ctx, next) => {

    ctx.body = {

        key: "hello koa-router v1 automatic"

    }

})

module.exports = router;

Since we export the router instance in hello.js, the obj parameter accepted by our whenLoadModule method is the router instance here.

So far, we have implemented the automatic import and reference of routes. In the future, we can concentrate on writing routes in app/api/v1. It is great that we can make the routes work by themselves without changing the app.js file.

Don't worry, there's more logic in our app.js. We say app.js as an entry file should look like an entry file. These routing logic can be thought of as an initialization operation. There will be more logic in the future, so we'll change the code to pull out the initialization logic.

##Initialization Manager

New folder core, new file core/init.js

 

init.js

    // core/init.js
    const requireDirectory = require('require-directory')
    const Router = require('koa-router')
    class InitManager {
        static initCore(app) {
            // Entry Method
            InitManager.app = app;
            InitManager.initLoadRouters();
        }
        static initLoadRouters() {
            function whenLoadModule(obj) {
                if (obj instanceof Router) {
                    InitManager.app.use(obj.routes())
                }
            }
            const apiDirectory = `${process.cwd()}/app/api` // Stitching Absolute Path
            requireDirectory(module, apiDirectory, {
                visit: whenLoadModule
            })
        }
    }

    module.exports = InitManager;

app.js

    // app.js
    const Koa = require('koa')
    const InitManager = require('./core/init')
    const app = new Koa();
    InitManager.initCore(app)
    app.listen(3001)
    console.log('listen 3001');

Execute `node app.js'in the terminal after writing, then go to the browser to access`http://localhost:3001/v1/hello/router` (or use the postman request) to see that we have successfully returned

{"key":"hello koa-router v1"}

#Summary

Now our routing architecture is really set up. From writing all routes in app.js to pulling out routes to automatic route introduction and registration, this is my exploration process, writing all routes in app.js in theoryWe can run inside, but we can't just be content to use this level, we need to use it better. Think more about how to be "lazy" so that we can improve our level, and the architecture we've designed can be complimented by others.

---

Copyright Notice: Free Reproduction - Non-Commercial - Non-Derived - Preserve Signature

Keywords: Javascript node.js http koa

Added by ++Sti++ on Sat, 11 Sep 2021 19:54:33 +0300