TSLab【第5回 Express勉強会】POST/DELETE
目次
- ・| 内容
- ・| POST Userの実装
- ・| DELETE Userの実装
- ・| さいごに
内容
前回もPUTのリファクタリングで時間を使ってしまったので今回はPOST/DELETEを一気に仕上げていきます。
バリデーションや処理自体はPUTの方がボリュームがあったのでPOST/DELETEはそこまで記述量が多くないと思います。
では早速内容にいきましょう。
POST Userの実装
POSTの処理フローとしては下記の通りになります。
- bodyのキーが一致しているかチェック
- name が文字列かチェック
- age が数値かチェック
- name が重複していないかチェック
- データを作成
- 結果をレスポンス
PUTと違いnameとageはどちらか欠けてもエラーを返すよう設計しました。
実際のコードは以下の通りです。
post_user.ts
import { Request, Response } from 'express'
import {
PARAMETER_NOT_MAYCH,
DUPLICATE_NAME,
PARAMETER_INVALID,
} from '../../constants/error'
import { Handler } from '../../core/handler'
import { User } from '../../models/index'
import { IPostUserParams } from '../../types'
import CheckUtils from '../../utils/check'
export class PostUser {
handler: Handler
params: IPostUserParams
constructor(req: Request, res: Response) {
this.handler = new Handler(req, res)
this.params = { ...req.params, ...req.body }
}
/**
* メイン処理
*/
async main() {
const validParams = ['name', 'age']
if (!CheckUtils.CheckMatchParams(this.params, validParams)) {
return this.handler.error(PARAMETER_NOT_MAYCH)
}
if (
typeof this.params.name !== 'string' ||
typeof this.params.age !== 'number'
) {
return this.handler.error(PARAMETER_INVALID)
}
const isDuplicateName = await this.checkDuplicateName()
if (!isDuplicateName) return this.handler.error(DUPLICATE_NAME)
const data = await this.createUser()
return this.handler.json<number>(data)
}
/**
* nameが一致するユーザーを取得
*/
async checkDuplicateName(): Promise<boolean> {
const response = await User.findAll({
where: {
name: this.params.name,
},
})
return !response.length
}
/**
* ユーザーを新規作成
*/
async createUser(): Promise<number> {
const response = await User.create({ ...this.params })
return response.id
}
}
PUTとパラメーターチェックの処理が異なるのでこちらは別途追加します。
utils/check.ts
/**
* パラメーターが一致しているかチェック
*/
static CheckMatchParams(params: {}, validParams: string[]): boolean {
return validParams.every((key) => Object.keys(params).includes(key))
}
APIができたらコントローラー側で呼び出す処理を追加します。
router/users/Controller.ts
import { Router } from 'express'
import { GetUsers } from './users/get_users'
import { PutUser } from './users/put_user'
import { PostUser } from './users/post_user'
const router = Router()
router.get('/', (req, res, next) => {
new GetUsers(req, res).main().catch(next)
})
router.put('/:id', (req, res, next) => {
new PutUser(req, res).main().catch(next)
})
// ここから追加
router.post('/', (req, res, next) => {
new PostUser(req, res).main().catch(next)
})
// ここまで追加
export default router
実装としてはこれだけです!
あとは実行して問題がなければ完了になります!
DELETE Userの実装
DELETEの処理フローとしては下記の通りになります。
- 対象のユーザーが存在するかチェック
- 対象のユーザーを削除
- 結果をレスポンス
処理自体はDELETEが一番シンプルですね。
実際のコードは以下の通りです。
users/delete_user.ts
import { Request, Response } from 'express'
import { NO_DATA_EXISTS } from '../../constants/error'
import { Handler } from '../../core/handler'
import { User } from '../../models/index'
export class DeleteUser {
handler: Handler
id: number
constructor(req: Request, res: Response) {
this.handler = new Handler(req, res)
this.id = Number(req.params.id)
}
/**
* メイン処理
*/
async main() {
const user = await User.findByPk(this.id)
if (!user) return this.handler.error(NO_DATA_EXISTS)
const data = await this.deleteUser(user)
return this.handler.json<boolean>(data)
}
/**
* ユーザーを削除
*/
async deleteUser(deleteUser: User): Promise<boolean> {
const response = await deleteUser.destroy()
return Boolean(response)
}
}
こちらもルーター側に追加したか完了です。
routes/users/Controller.ts
import { Router } from 'express'
import { GetUsers } from './users/get_users'
import { PutUser } from './users/put_user'
import { PostUser } from './users/post_user'
import { DeleteUser } from './users/delete_user'
const router = Router()
router.get('/', (req, res, next) => {
new GetUsers(req, res).main().catch(next)
})
router.put('/:id', (req, res, next) => {
new PutUser(req, res).main().catch(next)
})
router.post('/', (req, res, next) => {
new PostUser(req, res).main().catch(next)
})
// ここから追加
router.delete('/:id', (req, res, next) => {
new DeleteUser(req, res).main().catch(next)
})
// ここまで追加
export default router
さいごに
第一回の環境構築回から始まりやっとCLUDの基本的なAPIが出揃いました!
ここまででExpressの超基本的なことが出来るようになったので、あとは応用でアプリケーションが作成可能になったと思います。
次回はまた横道に逸れて、MongoDBでDB操作ができるよう構築を進めていこうと思います!