> For the complete documentation index, see [llms.txt](https://nodelover.gitbook.io/koa-todo-api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://nodelover.gitbook.io/koa-todo-api/an-zhuang-cha-jian.md).

# 安装插件

## 安装 body 解析插件

koa 仅仅只提供最简单的功能，而不提供请求的body解析，所以我们需要一个解析body的插件。\
所有的插件我们都可以在[这里](https://github.com/koajs/koa/wiki)找到。

```
npm install koa-better-body -S
```

我们自己来写代码提示文件，在 node\_modules/@types 目录下面新建 `koa-better-body` 文件夹，再在里面新建 `index.d.ts`。

> 我为什么要把这个文件写在@types目录下，而不是在 tsconfig.json 里面重新增加一个 typeRoots 路径，是因为只有在@types目录下面才会被解析成模块。

假如我们不知道怎么写，我们首先安装一个同类型的插件，仿照着写。

```
npm i @types/koa-bodyparser -D
```

这样我们就可以仿照 koa-bodyparser 的代码提示文件写了。

插件的配置项具体是什么类型，在[这里](https://github.com/tunnckoCore/koa-better-body)可以找到。

完成的文件如下

```
import *　as Koa from 'koa';
import * as formidable from 'formidable';

declare module "koa"{
    interface Request {
        body: any,
        files: any,
        fields: any
    }
}

declare function bodyParser(opts? : {
    fields?: boolean | string,
    files?: boolean | string,
    multipart?: boolean,
    textLimit?: string,
    formLimit?: string,
    urlencodedLimit?: string,
    jsonLimit?: string,
    bufferLimit?: string,
    jsonStrict?: boolean,
    detectJSON?: () => any,
    strict?: boolean,
    onerror?: () => any,
    extendTypes?: Object,
    IncomingForm?: formidable.IncomingForm,
    handler?: GeneratorFunction,
    querystring?: Object,
    qs?: Object,
    delimiter?: string,
    sep?: string,
    buffer?: boolean
}): Koa.Middleware;

declare namespace bodyParser {}

export = bodyParser;
```

## 安装路由插件

```
npm install koa-better-router -S
```

以同样的方式，我们创建`@types/koa-better-router/index.d.ts`。

```
npm i @types/koa-router -D
```

我们可以仿照 koa-router 写，当然我们前提已经看完了 koa-better-router README.md 的 API。

```
import * as Koa from 'koa';

declare class Router{
    routes: Array<any>;
    get(path: string, fn: (ctx: Router.IRouteContext, next: () => Promise<any>) => any) : any;
    post(path: string, fn: (ctx: Router.IRouteContext, next: () => Promise<any>) => any): any;
    put(path: string, fn: (ctx: Router.IRouteContext, next: () => Promise<any>) => any): any;
    del(path: string, fn: (ctx: Router.IRouteContext, next: () => Promise<any>) => any): any;
    loadMethods() : Router;
    createRoute(method: string, path: string | Function,fn?: any, ...args: Function[]) : Object;
    addRoute(method: string, path: string | Function,fn?: any, ...args: Function[]) : Object;
    getRoute(method: string, path: string | Function, fn?: any, ...args: Function[]) : Object;
    addRoutes(...fn: Array<any>) : Router;
    getRoutes() : any[];
    groupRoutes(dest: any, src1: any, src2: any) : any;
    extend(router: Object): Router;
    middleware(): Koa.Middleware;
    legacyMiddleware(): GeneratorFunction;
}

declare module "koa"{
    interface Context {
        params: any
    }
}

declare namespace Router{
    export interface IRouteContext extends Koa.Context{
        route: any
    }

    export interface IOptions {
        notFound?: (ctx: IRouteContext, next: () => Promise<any> ) => any;
        prefix?: string
    }
}


declare function RouterFactory(opts? : Router.IOptions) : Router;

declare namespace RouterFactory {}

export = RouterFactory
```

## Convert

当我们使用此刻的这些插件的时候，可能会抛出一个警告，所以我们需要 koa-convert 这个工具。

```
npm i koa-convert -S
```

此时修改我们的 `index.ts`

```
import * as Koa from 'koa';
import * as bodyParser from 'koa-better-body';
import * as Router from 'koa-better-router';
import * as Convert from 'koa-convert';

const router = Router().loadMethods();

const app = new Koa();

router.get('/hello', async (ctx, next) => {
  ctx.body = `Hello world! Prefix: ${ctx.route.prefix}`
  await next()
});

router.get('/foobar', async (ctx, next) => {
  ctx.body = `Foo Bar Baz! ${ctx.route.prefix}`
  await next()
})

const api = Router({ prefix: '/api' })
api.extend(router)

app.use(Convert(bodyParser()));
app.use(router.middleware());
app.use(api.middleware());

app.listen(3000, () => {
    console.log("Server Stared on http://localhost:3000")
});
```

运行起来，看一看。
