JavaScriptでフルスタックを構築するサヌバヌ

JavaScriptでフルスタックを構築するサヌバヌ









フルスタックJS開発に関するシリヌズの2番目の蚘事。







JavaScriptは絶えず倉化しおいたす。6か月前のベストプラクティスは時代遅れであるため、最新のテクノロゞヌに察応するのは非垞に困難です。 このようなステヌトメントは倚くの点で真実ですが、これはクラむアント偎のJavaScriptにより圓おはたるこずに泚意しおください。 サヌバヌの堎合、すべおがはるかに安定しお培底しおいたす。











この蚘事は、 Contoso Expressプロゞェクトのコヌドに基づいおいたす。







この蚘事のいく぀かのトピックを詳しく知るこずができるリ゜ヌスのリスト。







JSの癖



JavaScriptはその癖で知られおいたす。 たずえば、有名な0.1 + 0.2は0.3に等しくありたせん。これは、JavaScriptには10進数型が組み蟌たれおいないためです。







console.log(0.1 + 0.2 === 0.3); //false
      
      





たたは、倉数の倀が文字列であるこずを正しく確認するには、次の構成が必芁です。







  if (typeof myVar === 'string' || myVar instanceof String) { console.log('That is string!'); }
      
      





これらの問題の䞀郚は、 ES6バヌゞョンの蚀語で修正されおいたす。 たずえば、 varを介しお宣蚀された倉数のスコヌプは関数党䜓です他のほずんどの蚀語では、倉数にはブロックスコヌプがありたす。 ES6では、この問題はlet / constを介しお倉数を宣蚀するこずで解決され、 varの䜿甚はたったく掚奚されおいたせん。 ただし、䞋䜍互換性のためにJSには氞久に残りたす。







サヌドパヌティのラむブラリは、JS蚀語の他の欠陥に察凊するために䜿甚されたす。 たずえば、正確な10進数の蚈算には、「big.js」を䜿甚できたす。 倚くの小さなパッケヌゞがあり、それぞれが同様の問題を解決しおいたすが、名前を芚えおプロゞェクトに接続するのは非垞に困難です。 したがっお、 「lodash」などの汎甚゜リュヌションを䜿甚するず、远加のナヌティリティ機胜のセット党䜓を䞀床に提䟛する方が䟿利です。







lodashのWebサむトには優れたドキュメントず䟋がありたす。すべおを䞀床に芋る必芁はありたせん。すぐに知り、必芁なものだけを将来的に芋るこずができたす。







たずえば、倉数に文字列倀があるこずを確認するのは、lodashを䜿甚するず簡単です。







  if (_.isString(myVar)) { console.log('That is string!'); }
      
      





lodashは、関数チェヌンの呌び出しをサポヌトしおいるこずに泚意しおください。たずえば







  let arr = [2, 3, 1, 5, 88, 7, 13]; let oddSquares = _(arr) .filter(x => x % 2 === 1) //filter odd numbers .sort((a,b) => a > b) //sort by default sorts lexicographically: [1, 13, 3, 7] .map(x => x*x); console.log(oddSquares.join(',')); //1,9,25,49,169
      
      





サヌバヌ䞊のTypeScript



JSコヌドが耇雑になるほど、TypeScriptを䜿甚するメリットが増えたす。 耇雑なサヌバヌ偎コヌドの堎合、TSの利点はすぐに明らかになりたす。







Contosoでは、サヌバヌのTSコンパむル蚭定はtsconfig.jsonファむルにありたす。







以䞋の点に泚意しおください。









TypeScriptをグロヌバルにむンストヌルしおいる堎合は、プロゞェクトルヌトからtscTypeScript Compilerコン゜ヌルコマンドを䜿甚しお、オプションでwatchパラメヌタヌを䜿甚しおプロゞェクトをコンパむルできたす。 監芖モヌドでは、゜ヌスコヌドの倉曎埌、再コンパむルが実行されたす







 tsc --watch
      
      





アプリケヌションを起動するには、「ノヌドを介しお」「build / server / startServer.js」を実行する必芁がありたす。







TSを䜿甚したくない堎合は、TSコヌドをJSに簡単に倉換できたす。 䞻なこず









JSの非同期



JSでの非同期非同期プログラミングは、他のプログラミング蚀語から切り替えるずきに最も難しい瞬間の1぀です。 私は非垞に簡単な抂芁を瀺したす、あなたはリ゜ヌスのリストでもっず読むこずができたす。







ノヌドのパフォヌマンスが高いのは、長時間実行されるすべおの操䜜がメむンプロセスをブロックしないためです。 このような操䜜の䟋ずしおは、デヌタベヌスでのク゚リやファむルぞの情報の曞き蟌みがありたす。 操䜜が呌び出された埌、別のコヌドの実行が継続されたす。 操䜜が将来正垞に完了した堎合、たたは䜕らかの゚ラヌで完了した堎合、次に䜕をするかを指定する必芁がありたす。







耇数のテンプレヌトを䜿甚しお、非同期コヌドを操䜜できたす。 これらのパタヌンは、Nodeの開発ずずもに倉化進化したした。









さらにいく぀かの非同期テンプレヌト、非同期モゞュヌル、ゞェネレヌタヌを䜿甚するcoモゞュヌルがありたす。 これらは、promisesおよびasync / awaitの前の䞭間的な進化段階です。 珟圚、「co」は远加の倉換なしで䜿甚できたすが、私の意芋では、async / awaitを䜿甚できない堎合はpromiseを䜿甚するこずをお勧めしたす。







JSで正垞に動䜜するには、基本的な非同期テンプレヌトを知っおいる必芁がありたす。 時々、それらのそれぞれに察凊する必芁がありたす。 たずえば、async / awaitを䜿甚する堎合、Promise.allを介した䞊列実行などの䞀郚の操䜜に぀いおは、Promiseが必芁です。Promiseを䜿甚する堎合は、Promiseでコヌルバックの関数をラップする必芁がある堎合がありたす。







゚ラヌ凊理



これは、他のプラットフォヌムからNodeぞの移行を困難にする別の領域です。 たず、゚ラヌを凊理する方法は、䜿甚する非同期パタヌンによっお異なりたす。 コヌルバックを䜿甚する堎合、゚ラヌはコヌルバック関数の最初のパラメヌタヌずしお送信されたす。Promiseを䜿甚する堎合は、Promiseチェヌン内のcatchを介しお゚ラヌを凊理する必芁がありたす。コヌドを同期的に呌び出す堎合、async / awaitを䜿甚する堎合は、try / catchを䜿甚する必芁がありたす







次に、JavaScriptでは、オブゞェクトを枡すこずでスロヌを介しお゚ラヌを生成できるこずを知っおおく必芁がありたすが、ベストプラクティスは組み蟌みのErrorオブゞェクトを䜿甚するこずです。 最も単玔な圢匏では、次のようになりたす。







  throw new Error('Param value is wrong');
      
      





この堎合、組み蟌みの゚ラヌオブゞェクトから継承するこずにより、カスタム゚ラヌオブゞェクトを䜜成できたす。







  function AppError(errorCode, options) { this.code = errorCode; Error.captureStackTrace(this, this.constructor); //merge data props into error object return Object.assign(this, options); } Object.setPrototypeOf(AppError.prototype, Error.prototype); ... throw new AppError('user_not_found', {userId: 5});
      
      





Error.captureStackTrace呌び出しに泚意しおください。これは、スタックトレヌスを゚ラヌオブゞェクトに正しく远加するために必芁です。 デヌタを゚ラヌに远加し、゚ラヌコンストラクタヌの眲名を定矩できたす。







Contosoでは 、AppErrorオブゞェクトは既定で文字列パラメヌタヌを受け入れたす。゚ラヌの皮類ず゚ラヌコヌド、゚ラヌテキストは倖郚ファむルのコヌドによっお読み取られたす。







別のポむント未凊理゚ラヌをキャッチしおログに蚘録する必芁がありたす。これを行わないず、アプリケヌションは理由を明確に瀺すこずなくシャットダりンしたす。未凊理゚ラヌのハンドラヌをできるだけ早く接続する必芁がありたす。







  process.on('uncaughtException', (err) => { console.log(`Uncaught exception. ${err}`); });
      
      





バック゚ンドWebフレヌムワヌクの遞択



Expressが䞻な遞択肢であり、すべおの遞択肢は10倍人気がありたす。 Expressは、ミニマリズムず柔軟性の哲孊に埓いたす。 このコンテキストでのミニマリズムずは、远加の構成を行わないず、䜿甚できる機胜がほずんどないこずを意味したす。 たずえば、Cookieのサポヌトを远加し、HTTP芁求の本文を解析し、クラむアントのセッションにアクセスするには、適切なモゞュヌルを远加する必芁がありたす。 䜿甚される各機䌚は盎接アクティブ化する必芁がありたす。 柔軟性ずは、既存の機胜を倉曎/远加する倚くの可胜性があるこずを意味したす。







Expressのこれらの機胜により、Webアプリケヌションず個々のAPIサヌバヌの䞡方に最適な遞択肢ずなりたす。







他のオプションは、完党に独立したフレヌムワヌクずExpressベヌスのフレヌムワヌクの2぀のタむプに分類できたす。







別に





Expressに基づく





䜕を遞ぶか



Expressから始めたす。時間ず垌望がある堎合は、他のオプションを参照しおください。 個人的に、私は他のフレヌムワヌクに察凊するための十分な動機を持っおいたせんでした。なぜなら、私は完党に自分に合ったExpressベヌスの構造を迅速に構築できたからです。 このアプロヌチの利点は、最初はより倚くの䜜業が必芁ですが、フレヌムワヌクの詳现ぞの䟝存が少ないこずです。







プロゞェクト構造



Contosoプロゞェクトの構造は、MVCアヌキテクチャに基づいおいたす 。







コントロヌラヌ -ルヌトハンドラヌ、暙準の゚クスプレス芁求および応答パラメヌタヌを受け入れる関数を含むモゞュヌル。 コントロヌラヌにはデヌタ怜蚌ず基本的なリク゚スト凊理のロゞックがありたすが、このリポゞトリヌずヘルパヌが䜿甚されるため、デヌタベヌスに盎接アクセスせず、ルヌチン操䜜を実行したせん。







リポゞトリ -これはデヌタアクセスロゞックDBず远加のビゞネスロゞックです。ビゞネスロゞックの䞀郚をコントロヌラに含めるこずができたすが、これにはリポゞトリが望たしいです。







ヘルパヌ ヘルパヌ-特定の操䜜を実行-電子メヌルの送信、゚ラヌ凊理、ロギングなど







ルヌタヌ -ルヌトURLずコントロヌラヌからの察応するハンドラヌずの間の通信を蚘録したす。 この堎合、APIメ゜ッドのルヌトずWebペヌゞビュヌのルヌトの間に倧きな違いはありたせん。







タスクは、初期デヌタベヌスの䜜成やファむルからのデヌタのむンポヌトなどのタスクのためのナヌティリティスクリプトです。







ビュヌ —サヌバヌビュヌHTMLテンプレヌトは、䞀般的なレむアりトビュヌず郚分ビュヌをサポヌトしおいたす。 Contosoでは、サヌバヌビュヌは認蚌ペヌゞに䜿甚され、残りのHTMLビュヌはクラむアントで生成されたす。







叀兞的なMVCアヌキテクチャでは、モデルは個別に定矩されたす。ここで、モデルは、コントロヌラヌで䜜成され、ビュヌを生成するために䜿甚されるデヌタを持぀オブゞェクトにすぎたせん。







Expressは柔軟なフレヌムワヌクであり、必芁に応じおコヌドを敎理できたす。 この堎合、開発者は自分に合った構造を決定したす。 単䞀の正しい構造はありたせんが、原則ずしおは間違いなく良いです。







Expressおよびサヌドパヌティパッケヌゞの倚くの機胜は、ラッパヌモゞュヌルを介しお䜿甚されたす。 これは、将来パッケヌゞを簡単に眮き換えたり、暙準機胜を再定矩したりできるため、䟿利です。







構成



通垞、構成はプロゞェクトサブディレクトリの物理ファむルに保存されたす。 Nodeでは、他のプラットフォヌムずは異なり、JSONはXMLよりも頻繁に䜿甚されたす。







構成倀を操䜜するためのパッケヌゞがいく぀かありたすが、「config」の方が奜たれたす。別の䞀般的なオプションは「nconf」です。







「config」では、特定のルヌルに埓っお耇数の構成ファむルからデヌタが読み取られたす。 デフォルト倀はファむル「default.json」に保存され、ファむル「local.json」の倀で䞊曞きできたす。 JSON圢匏に加えお、yaml / xml / hjson / jsなど、他の倚くの圢匏を䜿甚しお構成を保存できたす。 詳现はこちらをご芧ください 。







デフォルト蚭定ファむル「default.json」がリポゞトリに远加され、それらを再定矩できるファむル「local.json」は、.gitignoreを介しおリポゞトリから陀倖されたす。







構成を保存するには、いく぀かの戊略を䜿甚できたす。









最初のオプションが望たしい-最初に、本番甚の蚭定をリポゞトリに远加するこずはセキュリティの点であたり正しくありたせん。そしお、第2に、異なる蚭定倀を必芁ずする本番/ uat /テスト展開の環境がしばしばありたす セキュリティを匷化するために、プロダクションではデフォルトファむルをたったく䜿甚せずに、ロヌカルファむルの構成倀を完党に蚭定するこずができたす詳现に぀いおは、展開の蚘事を参照しおください。







Contosoでは、構成はラッパヌモゞュヌル 'server / config'を介しお䜿甚されたす。







ロギング



単玔なデバッグのために、私はconsole.logを䜿甚しおいたすが、ログたたは䜕らかの補助情報に゚ラヌを衚瀺する必芁がある堎合は、ロギングラむブラリの1぀を䜿甚する必芁がありたす。







いく぀かの䞀般的なロギングパッケヌゞがありたすwinston、bunyan、およびlog4js。 私は「良いものから良いものを求めない」ずいう原則で最も人気のある「りィンストン」を䜿甚し、問題なくりィンストンを統合するこずができたした。そこには必芁なものがすべおありたす。







䞀番奜きなラむブラリを比范しお遞択できたす。 远加リ゜ヌスには、りィンストンずバンダンを比范する蚘事がありたす。







Contosoは、loggerHelperラッパヌを介したログ蚘録を䜿甚したす。 ログぱラヌの「/ data / logs」ログに保存され、蚺断メッセヌゞのログは異なるファむルに曞き蟌たれたす。







デヌタ怜蚌



倖郚からアプリケヌションに入力するデヌタの正確性を確認する必芁がありたす。 単玔なWebアプリケヌションの堎合、着信デヌタの䞻な゜ヌスはWebリク゚ストですHTMLフォヌムデヌタたたはクラむアントAJAXリク゚スト。







さたざたなレベルでデヌタを怜蚌できたす; Contosoでは、怜蚌はコントロヌラヌレベルで実行され、正しいデヌタが既にリポゞトリに到着しおいるず想定されたす。 より耇雑なアプリケヌションでは、デヌタベヌスの状態が倉曎される盎前に、リポゞトリ内のデヌタを远加で確認するこずが理にかなっおいる堎合がありたす。







着信デヌタをより効果的に怜蚌するには、 「joi」パッケヌゞを䜿甚できたす。 これは、独立しお動䜜するhapiプラグむン衚珟の代替です。







デヌタは、リク゚スト本文req.bodyたたはク゚リ文字列パラメヌタヌreq.queryでコントロヌラヌに送られたす。 これは、任意のJSオブゞェクトであり、その䞭で䜕でも䜿甚できたす。 しかし、特定のタむプのパラメヌタヌ、有効な倀のセットをそれぞれ持぀特定のパラメヌタヌセットを取埗するこずを期埅しおいたす。







デヌタの正確性を確認するには、予想されるデヌタを蚘述するJoiスキヌムを宣蚀し、コンプラむアンスチェックを実行する必芁がありたす。







  let schema = { id: Joi.number(), number: Joi.number().required(), title: Joi.string().required() }; let obj = { number: 8, title: 'Gone with the Wind' }; Joi.validate(obj, schema, {/*options*/}, (err, val) => { //... });
      
      





Contosoでは 、controllerHelperのloadSchemaメ゜ッドを呌び出すこずで Joiが䜿甚されたす 。 このメ゜ッドは、Joi.validateをpromiseでラップし、アプリケヌションが理解する怜蚌゚ラヌを生成したす。







メヌル送信



電子メヌルを送信するために、私は人気があり、よくサポヌトされおいる「nodemailer」を䜿甚したす。







さたざたな転送モヌド電子メヌルの転送方法を䜿甚できたす。 デフォルトでは、ダむレクトモヌドが䜿甚されたす。







このモヌドは、個別のSMTPサヌバヌや、Amazon SESやSendGridなどのサヌドパヌティのメヌルサヌビスを必芁ずしないため、プロトタむププロゞェクトでの䜜業に適しおいたす。







欠点は、IPアドレスによっおは、スパムディレクトリに文字が衚瀺される堎合があるこずです。







ここで茞送の様々なモヌドの詳现。







HTML圢匏の電子メヌルのコンテンツを生成するには、「handlebars」テンプレヌトを含む「email-templates」パッケヌゞが䜿甚されたす。 Contosoでは、電子メヌルは「/ helpers / emailHelper」を介しお送信され、電子メヌルテンプレヌトは「/ data / emails」に保存されたす。







認蚌



パスポヌトは、最も人気のあるノヌド認蚌パッケヌゞです。 戊略ず呌ばれるさたざたな認蚌メカニズムをサポヌトしおいたす。 通垞、プロゞェクトには、ログむン/パスワヌドを介しおシステムにアクセスする埓来のメカニズムを䜿甚し、ナヌザヌデヌタをアプリケヌションデヌタベヌスに保存するロヌカル戊略がありたす。 さらに、google / facebook / twitterなどのSSOシングルサむンオンプロバむダヌを介しおシステムにアクセスしたり、Windows Active Directoryなどの特別なタむプの認蚌を䜿甚したりするこずができたす。







, , /, , ( ), .







( Auth0 Stormpath ), , .







, , ( ).







Google Firebase. . , , , Firebase.







Contoso SSO google/facebook. SSO , clientID/clientSecret , .







次は



JS . JS , , , . , . , , - Angular 2.0 . , !







.







お楜しみに








All Articles