Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8825

Nodejs用のモデルライブラリを作ってみた【Express】

$
0
0

リポジトリ

https://github.com/kbc18a11/oreoreExpress
ライブラリ本体はoreoreExpress/database/AbstractModel.jsです。

解説用の構成や注意点

  • FW:Express
  • ディレクトリ構成:WebStormの新規Expressプロジェクトの状態にプロジェクト名/databaseプロジェクト名/modelというディレクトリを生成
  • 本記事はチーム開発のメンバーのマニュアルとしても書いていますので、ライブラリには直接関係ないことも書いています。

今回利用しているtestsテーブルは以下の構成になっています

idtextcreated_atupdated_at

使い方

リポジトリのものを利用するのであれば、以下のコマンドを実行してください。

npm install mysql2

ライブラリだけを使用するのであれば、mysql2date-utlisをインストールします

npm install mysql2
npm install date-utlis

そして以下のとおり、mysql2の設定ファイルを作ります。

プロジェクト名/database/mysqlConnection
constmysql=require('mysql2');//MySQLの接続設定constconnection=mysql.createConnection({host:'localhost',user:'',password:'',database:''}).promise();module.exports=connection;

下記の通り、作りたいモデルクラスに設定します。
また以下のメソッドをオーバーライド、オーバーロードします。
abstractTABLE_NAME
abstractVALIDATIONRULES
update

メソッドabstractTABLE_NAMEは、連携しているテーブル名のです。
メソッドabstractVALIDATIONRULESは、バリエーションルールを記述する所です。
バリエーションのルールはvalidatorjsのものになります。
https://www.npmjs.com/package/validatorjs

プロジェクト名/model/Tests
constAbstractModel=require('./AbstractModel');constconnection=require('../database/mysqlConnection');require('date-utils');classTestsextendsAbstractModel{constructor(){super();}/**
     * テーブル名
     * @override
     * @returns {string}
     */staticgetabstractTABLE_NAME(){return'tests';}/**
     * バリデーションルール
     * @override
     * @return {Object}
     */staticgetabstractVALIDATIONRULES(){return{get:{rule:{id:'required|integer'},errorMessage:{required:'必須項目です。',integer:'数値で入力してください'}},//POSTリクエスト用post:{rule:{text:'required'},errorMessage:{required:'必須項目です。',}},//PUTリクエスト用put:{rule:{id:'required|integer',text:'required'},errorMessage:{required:'必須項目です。',integer:'数値で入力してください'}},//DELETEリクエスト用delete:{rule:{id:'required|integer'},errorMessage:{required:'必須項目です。',integer:'数値で入力してください'}}};}/**
     * UPDATE文の準備を行って、親クラスのupdate()に実行をさせる
     * @param {Object} insertParam
     */staticasyncupdate(insertParam){//UPDATE文constsql=`UPDATE ${this.abstractTABLE_NAME} SET text = ?,updated_at = ? WHERE id = ?`;//create_at用の日付時間取得insertParam.updated_at=newDate().toFormat('YYYY-MM-DD HH:MI:SS');//SQLの実行awaitsuper.update(insertParam,sql);}}module.exports=Tests;

機能

基本的にライブラリの機能を使う場合は、Expressのルーティングファイルの無名関数にasyncを付与します。

プロジェクト名/routes/ルーティングファイル
router.get('/tests',async(req,res,next)=>{

そして、ルーティングファイルで以下のライブラリを取り組みます。

プロジェクト名/routes/ルーティングファイル
constexpress=require('express');constrouter=express.Router();constvalidator=require('validatorjs');constTests=require('../model/Tests');

ライブラリでデータベースを操作するメソッドは、Promiseオブジェクトがかかわっているため、呼び出しの際には、awaitを付与します。

プロジェクト名/routes/ルーティングファイル
//レコードをすべて取得awaitTest.all()//引数idのカラム取得awaitTest.find(id)//引数idの存在確認を行うawaitTest.existId(id)//引数paramの値で新規登録を行うawaitTest.insert(param)//引数paramの値で更新を行うawaitTest.update(param)//引数idのレコードを削除するawaitTest.delete(id)

all() レコードをすべて取得

プロジェクト名/routes/test.js
/**
 * @GET
 * testsのレコードをすべて取得
 */router.get('/tests',async(req,res,next)=>{try{//レコードをすべて取得constallRows=awaitTests.all();//レコードを返すreturnres.send(allRows);}catch(error){//レコードの取得失敗時console.log(error);res.status(500);returnres.send({'error':'サーバー側でエラーが発生しました'});}});

http://localhost:3000/testsGETでアクセスします。

http
[{"id":1,"text":"これはテストです","created_at":"2020-06-18T16:50:45.000Z","updated_at":null},{"id":2,"text":"これはテストです","created_at":"2020-06-18T16:50:50.000Z","updated_at":null},{"id":3,"text":"これはテストです","created_at":"2020-06-18T16:50:51.000Z","updated_at":null}]

find(id) 引数idのカラム取得

プロジェクト名/routes/test.js
/**
 * @GET
 * 指定されたidのカラムを取得
 */router.get('/tests/:id',async(req,res,next)=>{//バリデーションの検証を受ける値constverificationValue={id:req.params.id}//バリデーションの結果にエラーがあるかのチェックconstvalidation=newvalidator(verificationValue,Tests.abstractVALIDATIONRULES.get.rule,Tests.abstractVALIDATIONRULES.get.errorMessage);if(validation.fails()){//エラーを422で返すreturnres.status(422).send({errors:validation.errors.all()});}try{//レコードを取得constrow=awaitTests.find(verificationValue.id);//レコードを返すreturnres.send(row);}catch(error){//レコードの取得失敗時console.log(error);res.status(500);returnres.send({'error':'サーバー側でエラーが発生しました'});}})

http://localhost:3000/(testのidを指定)GETでアクセスします。

http
[{"id":1,"text":"これはテストです","created_at":"2020-06-18T16:50:45.000Z","updated_at":null}]

また、URIのidを指定する所が以下のとおり数値以外の場合は、エラーメッセージを返します。
http://localhost:3000/aaaa77

http
{"errors":{"id":["数値で入力してください"]}}

insert() 引数paramの値で新規登録を行う

プロジェクト名/routes/test.js
/**
 * @POST
 * testsに新しいレコードを挿入
 */router.post('/test',async(req,res,next)=>{//バリデーションの検証を受ける値constverificationValue={text:req.query.text}//バリデーションの結果にエラーがあるかのチェックconstvalidation=newvalidator(verificationValue,Tests.abstractVALIDATIONRULES.post.rule,Tests.abstractVALIDATIONRULES.post.errorMessage);if(validation.fails()){//エラーを422で返すreturnres.status(422).send({errors:validation.errors.all()});}try{//レコードの挿入開始awaitTests.insert({text:req.query.text});returnres.send({'insertResult':true});}catch(error){//レコードの挿入失敗時console.log(error);returnres.status(500).send({'insertResult':false});}});

http://localhost:3000/test?text=テストやりたいPOSTでアクセスします。

http
[{"id":1,"text":"これはテストです","created_at":"2020-06-18T16:50:45.000Z","updated_at":null}]

リクエストのボディにtextがない場合は、エラーメッセージを返します。

http
{"errors":{"text":["必須項目です。"]}}

update(param) 引数paramの値で更新を行う existId(id) 引数idの存在確認を行う

プロジェクト名/routes/test.js
/**
 * @PUT
 * レコードの更新
 */router.put('/test/:id',async(req,res,next)=>{//バリデーションの検証を受ける値constverificationValue={id:req.params.id,text:req.query.text}//バリデーションの結果にエラーがあるかのチェックconstvalidation=newvalidator(verificationValue,Tests.abstractVALIDATIONRULES.put.rule,Tests.abstractVALIDATIONRULES.put.errorMessage);if(validation.fails()){//エラーを422で返すreturnres.status(422).send({errors:validation.errors.all()});}//idは存在しないか?if(!awaitTests.existId(verificationValue.id)){//エラーを422で返すreturnres.status(422).send({errors:{id:['idが存在しません']}});}try{//レコードの更新開始awaitTests.update(verificationValue);returnres.send({'updateResult':true});}catch(error){//レコードの更新失敗時console.log(error);returnres.status(500).send({'updateResult':false});}});

http://localhost:3000/test?text=テストやりたいPUTでアクセスします。

http
{"updateResult":true}

URIのidを指定する所が以下のとおり数値以外やリクエストのボディにtextがない場合は、エラーメッセージを返します。
http://localhost:3000/test/aaa

http
{"errors":{"id":["数値で入力してください"],"text":["必須項目です。"]}}

そして、find(id)の引数のidがレコードに存在しない場合、このようなエラーを返します

http
{"errors":{"id":["idが存在しません"]}}

delete(id) 引数idのレコードを削除する

プロジェクト名/routes/test.js
/**
 * @DELETE
 * レコードの削除
 */router.delete('/test/:id',async(req,res,next)=>{//バリデーションの検証を受ける値constverificationValue={id:req.params.id,}//バリデーションの結果にエラーがあるかのチェックconstvalidation=newvalidator(verificationValue,Tests.abstractVALIDATIONRULES.delete.rule,Tests.abstractVALIDATIONRULES.delete.errorMessage);if(validation.fails()){//エラーを422で返すreturnres.status(422).send({errors:validation.errors.all()});}//idは存在しないか?if(!awaitTests.existId(verificationValue.id)){//エラーを422で返すreturnres.status(422).send({errors:{id:['idが存在しません']}});}try{//レコードの削除開始awaitTests.delete(verificationValue.id);returnres.send({'deleteResult':true});}catch(error){//レコードの削除失敗時console.log(error);returnres.status(500).send({'deleteResult':false});}})

http://localhost:3000/(testのidを指定)DELETEでアクセスします。

http
[{"id":1,"text":"これはテストです","created_at":"2020-06-18T16:50:45.000Z","updated_at":null}]

URIのidを指定する所が以下のとおり数値以外の場合は、エラーメッセージを返します。
http://localhost:3000/aaaa77

http
{"errors":{"id":["数値で入力してください"]}}

そして、find(id)の引数のidがレコードに存在しない場合、このようなエラーを返します

http
{"errors":{"id":["idが存在しません"]}}

Viewing all articles
Browse latest Browse all 8825

Trending Articles