Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

[Node.js] Express を TypeScript で書く - ルーティング編

More than 1 year has passed since last update.

はじめに

一応、前回の記事の続きとなっております。

環境は以下を前提としてます。

  • Windows 10
  • Node.js 10.10.0
  • Express 4.16.3
  • TypeScript 3.0.3
  • Visual Studio Code 1.26.1

準備

ルーティングを書く前に下準備をします。

今回設計するAPI

今回は別に外部に公開するわけでもなく、練習用なので最小限な感じで考えます。
必要な機能としては、以下の通り。

  • ユーザ作成、参照
  • ログイン、ログアウト
  • 記事の取得、一覧、投稿、検索

これらをAPIとしてURLに起こして行きます。

ダミーコードの準備

今回はルーティングの実装は書かず、ルーティングだけ先に実装する流れで作りたいので、リクエストしたらエラーを返すだけのダミーコードを用意します。

src/noImpl.ts
import * as Express from 'express';

export default function notImplemented(req: Express.Request, res: Express.Response, next: Express.NextFunction) {
    res.status(501).json({ message: 'Not Implemented.' });
}

コードを書く

思考錯誤しながら書いて最終的には以下の通りにまとまりました。
基本、CRUDを意識しつつ、API1つ1つがユニークになるように。

このへんはTypeScriptだからといって書き方に差異が出る所はあまりないと思います。

src/routes/articles/index.ts
import * as Express from 'express';
import noImpl from '../../noImpl';

const router = Express.Router();

// 全ユーザの記事一覧取得
router.get('/', noImpl);

// ログインしてるユーザの記事投稿
router.post('/', noImpl);

export default router;
src/routes/auth/index.ts
import * as Express from 'express';
import noImpl from '../../noImpl';

const router = Express.Router();

// ログイン処理
router.post('/login', noImpl);

// ログアウト処理
router.delete('/logout', noImpl);

// article 自体の READ, UPDATE, DELETE は /user/:user/article で行うようにする。

export default router;
src/routes/user/index.ts
import * as Express from 'express';
import noImpl from '../../noImpl';
import article from './article';

const router = Express.Router();

// ユーザの新規作成
router.post('/new', noImpl);

// ユーザ情報の取得
router.get('/:user', noImpl);

// ユーザの情報更新
router.put('/:user', noImpl);

// ユーザの削除
router.delete('/:user', noImpl);

// ユーザ毎の記事表示用ルーティング
router.use('/:user/article', article);

export default router;

user/article/index.ts では 子のパラメーターも使えるようにしたいので Express.Router({ mergeParams: true }) の指定をしています。

src/routes/user/article/index.ts
import * as Express from 'express';
import noImpl from '../../../noImpl';

const router = Express.Router({ mergeParams: true });

// ユーザの記事一覧
router.get('/list', noImpl);

// 記事単体取得
router.get('/:article', noImpl);

// 記事の更新
router.put('/:article', noImpl);

// 記事の削除
router.delete('/:article', noImpl);

export default router;

各々の記述が終わったら src/server.ts を直します。

src/server.ts
import * as Express from 'express';
import expressListEndpoints from 'express-list-endpoints';
import article from './routes/article';
import auth from './routes/auth';
import user from './routes/user';

const app = Express();

app.use('/article', article);
app.use('/auth', auth);
app.use('/user', user);

app.listen(3000, () => {
    console.log('Listen started at port 3000.');
    console.log(expressListEndpoints(app));
});

export default app;

実装したルーティングの確認用に新たに express-list-endpoints モジュールを導入してます。ルーティングの一覧をオブジェクトとして返してくれます。

npm install --save express-list-endpoints 

実行

ここまでのをビルドして実行すると express-list-endpoints によってコンソールに以下のように表示されます。

[ { path: '/article', methods: [ 'GET' ] },
  { path: '/article', methods: [ 'POST' ] },
  { path: '/auth/login', methods: [ 'POST' ] },
  { path: '/auth/logout', methods: [ 'DELETE' ] },
  { path: '/user/new', methods: [ 'POST' ] },
  { path: '/user/:user', methods: [ 'GET' ] },
  { path: '/user/:user', methods: [ 'PUT' ] },
  { path: '/user/:user', methods: [ 'DELETE' ] },
  { path: '/user/:user/article/list', methods: [ 'GET' ] },
  { path: '/user/:user/article/:article', methods: [ 'GET' ] },
  { path: '/user/:user/article/:article', methods: [ 'PUT' ] },
  { path: '/user/:user/article/:article', methods: [ 'DELETE' ] } ]

環境によってはヘルスチェックのためにルートに200を返すだけのコードも必要になってくるのですが、今回は省略。

次回は mongoDB 導入、接続編です。

[Node.js] Express を TypeScript で書く - MongoDB 接続編

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away