Node.js, Express, Typescript でREST APIを作成する手順をまとめます。自分が好きな情報を詰め込んでいるので、必要ない物は省いてカスタマイズしてください。
準備
Node.jsとnpmがインストール済みであることを node -v
, npm -v
のコマンドを実行して確認します。
開発を行うディレクトリで npm init
を実行して package.json が作成されることを確認します。いくつか質問が出てきますが全てそのままエンターを押して大丈夫です。
必要なライブラリなどのインストール
express(4系)やTypescript用のパッケージをインストールします。
$ npm install express --save$ npm install helmet --save$ npm install cors --save$ npm install mongodb mongoose --save$ npm install body-parser --save$ npm install moment --save$ npm install-D typescript @types/node
$ npm install-D @types/express @types/helmet @types/cors @types/mongoose
$ npm install-D ts-node
npmを使ってインストールしていきます。--save
のオプションをつけるとpackage.jsonの dependencies
に書き込まれます。-D
のオプションをつけるとpackage.jsonの devDependencies
(開発用) に書き込まれます。
ディレクトリ構成
コードの見通しを意識して、とりあえず次のような構成にします。
express-api
|---- /app
| └ app.ts
| └ /models
|ㅤ └ /routes
| └ /services
|
|---- package.json
app.tsこれを実行してサーバーを起動します
/modelsデータベースのモデル情報
/routes各apiの振り分け
/servicesサービスの処理
package.jsonパッケージ管理
Typescript準備
npx tsc --init
でtsconfig.jsonファイルを作成します。
tsconfig.jsonのtargetがes5だった場合、es6に変更します。
コードを書く
Hello World
まずはapp.ts
に以下を記述して、hello world が返却されることまで確認しましよう。
// ライブラリ読み込みimportexpressfrom'express';importhelmetfrom'helmet';importcorsfrom'cors';constapp=express();app.use(helmet());app.use(cors());constbodyParser=require('body-parser');//body-parserの設定app.use(bodyParser.urlencoded({extended:true}));app.use(bodyParser.json());constport=process.env.PORT||3000;// port番号を指定app.get('/helloWorld',(req,res)=>{res.status(200).send({message:'hello, world'});});//サーバ起動app.listen(port);console.log('listen on port '+port);
npx tsc
コマンドを実行するとコンパイルされ、jsファイルに変換されます。node app/app.js
コマンドでファイルを実行します。
コンソールに listen on port 3000
が表示されたことを確認したら、postmanを立ち上げて、http://localhost:3000/helloWorldにGETリクエストを送りましょう。
以下のようにレスポンスが返ってくれば成功です!!
{"message":"Hello, world"}
ts-node コマンドを利用すると、 tsc -> node の実行を自動的に行ってくれるので開発効率をあげることができます。npx ts-node app/app.ts
で実行してみましょう。
ソースコードの変更を検知するたびに自動的に再実行してくれる ts-node-dev というコマンドもありますが、今回は省略します。
いずれも Ctrl + C
で終了できます。
apiをディレクトリで分けて綺麗にする
まず、app.ts
を以下のように書き換えます。
// ライブラリ読み込みimportexpressfrom'express';importhelmetfrom'helmet';importcorsfrom'cors';constapp=express();app.use(helmet());app.use(cors());constbodyParser=require('body-parser');//body-parserの設定app.use(bodyParser.urlencoded({extended:true}));app.use(bodyParser.json());constport=process.env.PORT||3000;// port番号を指定// ------ ルーティング ------ //constrouter=require('./routes/');app.use('/',router);//サーバ起動app.listen(port);console.log('listen on port '+port);
これでroutesでルーティングする設定になりました。続いて、routes配下にindex.ts
を作成して、以下のように記述しましょう。
importexpressfrom'express';importhelmetfrom'helmet';importcorsfrom'cors';constapp=express();app.use(helmet());app.use(cors());// ルーティングするconstrouter=express.Router();// routerにルーティングの動作を記述するrouter.get('/helloWorld',(req,res)=>{res.status(200).send({message:'Hello, world'});});// -------------------------------------------------// 以下、何のルーティングにもマッチしないorエラー// -------------------------------------------------// いずれのルーティングにもマッチしない(==NOT FOUND)app.use((req,res)=>{res.status(404);res.render('error',{param:{status:404,message:'not found'},});});//routerをモジュールとして扱う準備module.exports=router;
ts-node コマンドを実行して、postmanでAPIを叩くと同じ結果が返ってくることを確認します。
続いて、サービスに設定していきましょう。
routes/index.tsにtestという名前のAPIを追加しましょう。
importexpressfrom'express';importhelmetfrom'helmet';importcorsfrom'cors';import{TestService}from'../services/TestService';constapp=express();app.use(helmet());app.use(cors());// ルーティングするconstrouter=express.Router();// routerにルーティングの動作を記述するrouter.get('/helloWorld',(req,res)=>{res.status(200).send({message:'Hello, world'});});router.get('/test',(req,res,next)=>{constservice=newTestService();service.test().then(result=>res.status(200).send(result)).catch(next);});// -------------------------------------------------// 以下、何のルーティングにもマッチしないorエラー// -------------------------------------------------// いずれのルーティングにもマッチしない(==NOT FOUND)app.use((req,res)=>{res.status(404);res.render('error',{param:{status:404,message:'not found'},});});//routerをモジュールとして扱う準備module.exports=router;
そして、services配下にTestService.ts
を作成して、以下のように記述します。
//インターフェースexportinterfaceITest{test:string;}//クラスexportclassTestService{publicasynctest():Promise<ITest>{return{test:'test1'}}}
http://localhost:3000/testにGETリクエストを送り、以下のレスポンスが返ってくると成功です!
{"test":"test1"}
続いてDB、Schemaを設定していきましょう。
mongoDB準備
mongoDBインストール
以下のコマンドでmongoDBをインストールします。brew tap mongodb/brew
brew install mongodb-community
mongodbの設定ファイルが/usr/local/etc/mongod.confに作成されます。
中身を確認するとログとデータベースの保存先のパスが記述されています。
mongoDBの起動brew services start mongodb-community
mongo コマンドでDBに接続できます。
データ追加
以下コマンドで app1db というデータベースを作成します。use app1db
データベースにswitchされるので、以下コマンドでデータを追加します。
> db.test_user.insert({"user":"user1","email":"user1@gmail.com"})> db.test_user.insert({"user":"user2","email":"user2@gmail.com"})
このコマンドで test_user というcollection (RDBMSでいうtableのようなもの) にBSONのフォーマットでuserなどの情報が保存される。
DB接続部分の追加
mongoDBに接続する部分をapp.tsに追加します。
// mongodbconstmongoose=require('mongoose');mongoose.Promise=global.Promise;constoptions={useUnifiedTopology:true,useNewUrlParser:true}mongoose.connect('mongodb://localhost:27017/app1db',options);mongoose.connection.on('error',function(err:any){console.error('MongoDB connection error: '+err);process.exit(-1);});
Modelファイルを作成する
models配下にTestMongoModel.ts
を作成し、以下を記述します。
importmongoosefrom'mongoose';//mongoDBに接続するためのライブラリconstSchema=mongoose.Schema;//mongoDBのスキーマを作るconstTestMongoSchema=newSchema({user:String,email:String},{collection:'test_user'});// スキーマをモデルとしてコンパイルし、それをモジュールとして扱えるようにするmodule.exports=mongoose.model('TestMongoModel',TestMongoSchema);
続いてDBからデータを取得する新規APIの準備をしていきましょう。
routes/index.tsに test/mongo/:user のパスを追加します。
router.get('/test/mongo/:user',(req,res,next)=>{const{user}=req.params;constservice=newTestMongoService();service.run(user).then(result=>res.status(200).send(result)).catch(next);});
さらにservices配下にTestMongoService.ts
を作成し、以下を記述します。
//インターフェースexportinterfaceITest{user:string;email:string;}//クラスexportclassTestMongoService{publicasyncrun(params:any):Promise<ITest>{consttestAll=awaitTestMongoModel.find();returntestAll;}}
パスパラメータを活かせてませんが、これで一通りできました。
postmanでhttp://localhost:3000/test/mongo/alluserでAPIを叩くと以下が表示されることを確認できれば成功です!!
[{"_id":"5f12ec4732c83a71dcf0e7db","user":"user1","email":"user1@gmail.com"},{"_id":"5f12ec5532c83a71dcf0e7dc","user":"user2","email":"user2@gmail.com"}]
参考資料
https://qiita.com/drafts/73cc7160d002a4989416/edit
https://qiita.com/notakaos/items/3bbd2293e2ff286d9f49