概要
TypeScript を使って型を定義しつつシリアライズします
環境
- macOS 11.6.5
- nodejs 17.8.0
- express 4.17.3
サンプルコード
- vim app.ts
import express from 'express'
const app = express()
const port = 3000
// ユーザプロファイルを管理するクラス
// 受け取ったリクエストはこのクラスのオブジェクトとして扱われる
// クラスはインタフェースを実装することで定義します
// そうすることで定義したインタフェースを返り値などの型定義に使用できます
interface UserProfileType {
name?: string,
age?: string
}
class UserProfile implements UserProfileType {
constructor(public name: string | undefined, public age: string | undefined) {
}
toJSON(): UserProfileType {
return {
name: this.name,
age: this.age,
}
}
// name と age が指定されているかの判定
validate(): boolean {
if (this.name === undefined || this.age === undefined) {
return false
} else {
return true
}
}
// レスポンス返却します
show(res: express.Response): void {
if (!this.validate()) {
let errMsg = {'Error': 'You must specify name and age.'}
res.send(JSON.stringify(errMsg))
} else {
res.send(JSON.stringify(this))
}
}
}
// express.Request を拡張してリクエストとして受け取るパラメータを再定義する
// 文字列または未定義のパラメータとして受け取る
interface UserProfileRequest extends express.Request {
query: {
name: string | undefined
age: string | undefined
}
}
// 受け取ったリクエストをそのままレスポンスとして返すルーティング
app.get('/', (req: UserProfileRequest, res: express.Response) => {
let profile = new UserProfile(req.query.name, req.query.age)
profile.show(res)
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
ポイント
UserProfileRequest インタフェースを定義して受け取るべきリクエストを定義しています
UserProfileRequest から UserProfile クラスのオブジェクトにシリアライズしていますが factory などを作って req から直接オブジェクトを生成してもいいかもしれません
クエリストリングは文字列でしか受け取れないので UserProfile.age も文字列で定義しています
本当は number として扱いたいので parseInt などを使ってどこかで変換してあげてもいいかもしれません
ちなみに undefined の部分はユニオンではなく Optional Property としても定義できます
interface UserProfileRequest extends express.Request {
query: {
name?: string
age?: string
}
}
あと toJSON の返り値の型も指定したかったので UserProfileType インタフェースを作成したあとで implements で UserProfile クラスを定義しています
最後に
今回は自力でシリアライズしましたが探せば便利なパッケージがあるかもしれません
0 件のコメント:
コメントを投稿