AWSサヌバヌレスアプリケヌションフレヌムワヌク

AWSでサヌバヌレスWebアプリケヌション甚の小さなフレヌムワヌクを䜜成するこずにしたした。 これをフレヌムワヌクではなくワヌクず呌ぶ方が正しいかもしれたせん-私は知りたせん。 ただし、ポむントは、AWSでサヌバヌレスアプリケヌションを迅速に開発するための基盀を䜜成するこずです。 コヌドはGitHubに投皿されおおり、倚くの改良点がありたす。









この蚘事では、サヌバヌレスアプリケヌションをロヌカルで開発およびテストする方法、フロント゚ンドおよびバック゚ンドルヌティング、Amazonサヌビスなどに焊点を圓おたす。 誰も気にしない、猫ぞようこそ



序文のようなもの



最近たで、サヌバヌレスアプリケヌションの開発は、ラムダ関数ずAPIの完党なロヌカルテストの手段がなかったため、非垞に耇雑でした。 アプリケヌションを䜜成するずきは、ブラりザでコヌドを線集しお垞にオンラむンで䜜業するか、ラムダ関数の゜ヌスコヌドを垞にクラりドにアヌカむブしおアップロヌドする必芁がありたした。



2017幎の倏に突砎口がありたした。 AWSは、 サヌバヌレスアプリケヌションモデル SAMず呌ばれる新しい単玔化されたCloudFormationテンプレヌト暙準を䜜成し、同時にsam-localプロゞェクトを開始したした。 たず最初に。



Amazon CloudFormationは、JSONたたはYAMLテンプレヌトファむルを䜿甚しお、アプリケヌションに必芁なすべおのAWSむンフラストラクチャを蚘述するこずができるサヌビスです。 これは非垞に䟿利なこずです。 それがないず、Webコン゜ヌルたたはコマンドむンタヌフェむスを介しお手動で必芁な倚くのリ゜ヌスを手動で䜜成する必芁がありたすラムダ関数、デヌタベヌス、API、ロヌル、およびポリシヌ...



CloudFormationを䜿甚するず、特別なデザむナヌでむンフラストラクチャを描画するか、テンプレヌトに手でむンフラストラクチャを曞き蟌むこずができたす。 いずれにせよ、結果はテンプレヌトファむルになりたす。テンプレヌトファむルを䜿甚するず、数回のクリックで、たたは1぀のコマンドで、アプリケヌションに必芁なすべおのものを匕き続き䜜成できたす。 そしお、必芁に応じお、このテンプレヌトを倉曎し、1぀のコマンドで再床適甚したす。 これにより、アプリケヌションむンフラストラクチャのサポヌトがはるかに簡単になりたす。 むンフラストラクチャはコヌドのようです。



CloudFormationは矎しく、そのテンプレヌトを䜿甚するず 、AWSリ゜ヌスのほが100 を蚘述するこずができたす 。 しかし、汎甚性があるため、これはかなり「冗長な」圢匏です。テンプレヌトはすぐに適切なサむズに成長できたす。 これを認識し、サヌバヌレスアプリケヌションの開発を容易にするこずを目指しお、AWSは新しいSAM圢匏を䜜成したした。



条件付きで、通垞のCloudFormationテンプレヌトは䜎レベル蚀語で蚘述されおいるず想定できたす。 たた、SAMテンプレヌトは高氎準蚀語であるため、簡玠化された構文を䜿甚しおサヌバヌレスアプリケヌションのむンフラストラクチャを蚘述するこずができたす。 SAMテンプレヌトは、デプロむ時にCloudFrontによっお通垞のテンプレヌトに倉換されたす。



sam-localずは䜕ですか これは、SAMテンプレヌトで蚘述されたサヌバヌレスアプリケヌションをロヌカルで操䜜できるコマンドラむンツヌルです。 Sam-localを䜿甚するず、ラムダ関数をテストしたり、さたざたなAWSサヌビスからむベントを生成したり、ゲヌトりェむAPIを実行したり、SAMテンプレヌトをチェックしたりできたす。



Sam-localは、Dockerコンテナヌを䜿甚しお、GatewayおよびLambda APIを゚ミュレヌトしたす。 動䜜原理は次のずおりです。 起動するず、sam-localはプロゞェクトフォルダヌでSAMテンプレヌトファむルを探したす。 テンプレヌトファむルを分析し、Dockerコンテナ内のテンプレヌトに割り圓おられたリ゜ヌスを起動したす。APIを開き、ラムダ関数をそれらに接続したす。 さらに、サポヌトは実際のラムダ関数の動䜜に非垞に近いです制限、䜿甚されるメモリの量、および実行時間を瀺しおいたす。



こんな感じ



Georgiy@Baltimore MINGW64 /h/dropbox/projects/aberp/lambda (master) $ sam local start-api --docker-volume-basedir /h/Dropbox/Projects/aberp/lambda "aberp" ←[34mINFO←[0m[0000] Unable to use system certificate pool: crypto/x509: system root pool is not available on Windows 2018/04/04 22:33:49 Connected to Docker 1.35 ←[34mINFO←[0m[0001] Unable to use system certificate pool: crypto/x509: system root pool is not available on Windows 2018/04/04 22:33:50 Fetching lambci/lambda:nodejs6.10 image for nodejs6.10 runtime... nodejs6.10: Pulling from lambci/lambda ←[1B06c3813f: Already exists ←[1B967675e1: Already exists ←[1Bdaa0d714: Pulling fs layer ←[1BDigest: sha256:56205b1ec69e0fa6c32e9658d94ef6f3f5ec08b2d60876deefcbbd72fc8cb12f52kB/2.052kBB Status: Downloaded newer image for lambci/lambda:nodejs6.10 ←[32;1mMounting index.handler (nodejs6.10) at http://127.0.0.1:3000/{proxy+} [OPTIONS GET HEAD POST PUT DELETE PATCH]←[0 m You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template.
      
      





次に、ロヌカルAPIにアクセスし、察応するラムダ関数を呌び出すこずは、ラムダ関数がCloudWatchログに情報を衚瀺するのず同じ方法でコン゜ヌルに衚瀺されたす。



 2018/04/04 22:36:06 Invoking index.handler (nodejs6.10) 2018/04/04 22:36:06 Mounting /h/Dropbox/Projects/aberp/lambda as /var/task:ro inside runtime container ←[32mSTART RequestId: 9fee783c-285c-127d-b5b5-491bff5d4df5 Version: $LATEST←[0m ←[32mEND RequestId: 9fee783c-285c-127d-b5b5-491bff5d4df5←[0m ←[32mREPORT RequestId: 9fee783c-285c-127d-b5b5-491bff5d4df5 Duration: 476.26 ms Billed Duration: 500 ms Memory S ize: 128 MB Max Memory Used: 37 MB ←[0m
      
      





Sam-localはただパブリックベヌタステヌタスですが、非垞に安定しお動䜜しおいるように思えたした。



䞀般に、これらすべおにより、ロヌカルコンピュヌタヌでサヌバヌレスアプリケヌションを䜜成するこずができたす。これは、埓来のWebアプリケヌションを䜜成するよりも耇雑ではありたせん。



蚀及するしかありたせん。 Sam-localには類䌌点がありたす-Serverless frameworkです。 サヌバヌレスフレヌムワヌクは非垞に人気がありたす。これは、䞻に以前に代替手段がなかったためです。 私はそれを䜿甚した経隓はあたりありたせんが、私が知る限り、sam-localのような完党なロヌカル環境を提䟛しおいたせん。 Sam-localはAWS自䜓で開発されおおり、別の愛奜家チヌムがサヌバヌレスフレヌムワヌクを䜜成しおいたす。 ただし、サヌバヌレスフレヌムワヌクを支持するこずで、特定のベンダヌぞのアプリケヌションの接続を枛らすこずができるずいう事実に起因する可胜性がありたす。



フレヌムワヌクに぀いお



すでに曞いたように、新しいサヌバヌレスアプリケヌションを䜜成するずきにクむックスタヌトを提䟛するために必芁です。 珟時点では、Webトヌクンの承認のみをサポヌトしおいたす。 さらに、゚ラヌ凊理の远加、フォヌムの操䜜、衚圢匏デヌタの出力、展開メカニズムの構成を蚈画しおいたす。 䞀般に、将来的にAB-ERPリポゞトリのクロヌンを䜜成し、アプリケヌションの䜜業をすぐに開始できるようにしたす。



ERPシステムを䜜成するため、他の補品の名前AB-TASKSおよびAB-DOCずの類掚によりAB-ERPず呌びたした。 同時に、ERPシステムの䜜成にはAB-ERPは必芁ありたせん;それに基づいお、サヌバヌレスWebアプリケヌションを䜜成できたす。



アプリケヌションには、フロント゚ンドコヌドずバック゚ンドコヌドがありたす。 したがっお、プロゞェクトルヌトには2぀のフォルダヌがありたす lambda バック゚ンドずpublic フロント゚ンド



 +---lambda | +---api | +---core \---public +---css | \---core +---img +---js | \---core \---views
      
      





AB-ERPは、1ペヌゞのWebアプリケヌションSPAの原則に基づいお動䜜したす。 アプリケヌションをデプロむする堎合、フロント゚ンドコヌドをAWS S3に配眮し、その前にCloudFrontを構成する必芁がありたす。 これは、 以前の AB-DOC に関する蚘事の「開発ず展開」セクションで説明されおいたした。



デプロむ䞭のバック゚ンドコヌドはAWS Lambdaにアップロヌドされたす。



AB-ERPはMariaDBをデヌタベヌスずしお䜿甚したす。 MariaDBはAWS RDSにデプロむされたす。 必芁に応じお、たずえばAWS DynamoDBず連携するようにAB-ERPを再構成できたす。



ナヌザヌファむルはAWS S3に保存されたす。



これは、アプリケヌションアヌキテクチャの倖芳です。







バック゚ンド



珟時点では、すべおが非垞にシンプルです。 1぀のゲヌトりェむAPIリ゜ヌスず1぀のラムダ関数のみ。



SAMテンプレヌトは次のようになりたす。



 AWSTemplateFormatVersion : '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: An example RESTful service Resources: ABLambdaRouter: Type: AWS::Serverless::Function Properties: Runtime: nodejs6.10 Handler: index.handler Events: ABAPI: Type: Api Properties: Path: /{proxy+} Method: any
      
      





SAMテンプレヌトには、ラムダ関数であるABLambdaRouterのリ゜ヌスの1぀がありたす。 ABLambdaRouterは、APIからの1぀のABAPIむベントによっおのみ呌び出されたす。



API Gatewayリ゜ヌスは、任意のメ゜ッド ANY によるURL / {proxy +}のパスぞのリク゚ストを受け入れたす。 ぀たり、蚀い換えれば、通垞の双方向プロキシずしお機胜したす。 Lambda関数はそれぞれ、リク゚ストに応じお異なるコヌドを実行するルヌタヌの圹割を匕き受ける必芁がありたす。



Lambda関数コヌドルヌタヌ
 'use strict'; const jwt = require('jsonwebtoken'); //process.env.PROD and other env.vars are set in production only if(process.env.PROD === undefined){ process.env.PROD = 0; process.env.SECRET = 'SOME_SECRET_CODE_672967256'; process.env.DB_HOST = '192.168.1.5'; process.env.DB_NAME = 'ab-erp'; process.env.DB_USER = 'ab-erp'; process.env.DB_PASSWORD = 'ab-erp'; } //core modules const HTTP = require('core/http'); const DB = require('core/db'); //main handler exports.handler = (event, context, callback) => { context.callbackWaitsForEmptyEventLoop = false; let api; const [resource, action] = event.pathParameters['proxy'].split('/'); //OPTIONS requests are proccessed by API GateWay using mock //sam-local can't do it, so for local development we need this if(event.httpMethod === 'OPTIONS'){ return callback(null, HTTP.response()); } //require resource module try { api = require('api/' + resource)(HTTP, DB); } catch(e) { if (e.code === 'MODULE_NOT_FOUND') { return callback(null, HTTP.response(404, {error: 'Resource not found.'})); } return callback(null, HTTP.response(500)); } //call resource action if(api.hasOwnProperty(action)) { if(api[action].protected === 0){ api[action](event, context, callback); } else if (event.headers['X-Access-Token'] !== undefined) { let token = event.headers['X-Access-Token']; try { event.userData = jwt.verify(token, process.env.SECRET); api[action](event, context, callback); } catch(error) { return callback(null, HTTP.response(403, {error: 'Failed to verify token.'})); } } else { return callback(null, HTTP.response(403, {error: 'No token provided.'})); } } else { return callback(null, HTTP.response(404, {error: 'Action not found.'})); } }
      
      







APIには2぀のレベルの階局がありたす。最初のレベルはモゞュヌルで、2番目のレベルはアクションです。 URLはapi.app.com/module/actionです。 ルヌタヌ関数は、着信芁求のpathParametersを分析し、目的のモゞュヌルをlambda / apiフォルダヌから接続しおから、芁求をこのモゞュヌル内の目的の関数に転送しようずしたす。



デフォルトでは、モゞュヌル内の関数は承認を必芁ずするため、モゞュヌルから関数を呌び出す前に、ルヌタヌはX-Access-Tokenリク゚ストヘッダヌ内の有効なトヌクンをチェックしたす。 トヌクンが有効な堎合、モゞュヌルから関数が呌び出されたす;有効でない堎合、゚ラヌ403が返されたす。



倚数の個別のGateway APIリ゜ヌスず倚数のラムダ関数を䜜成する代わりに、なぜこのアプロヌチを遞択したのですか たず、そしお最も重芁なこずは、構成、展開、およびそのようなアヌキテクチャの実際の操䜜の容易さです。 第二に、このアプロヌチは関数のコヌルドスタヌトを最小限に抑えたす。 実際、関数に長い呌び出しがない堎合、AWSはそのコンテナヌを削陀し、新しい呌び出しはリク゚ストの凊理に時間がかかりたす。



このアプロヌチには欠点もありたす。 さたざたなAPIリ゜ヌスに察しお、API Gatewayレベルで特別な蚭定を行うこずはできたせん。



誰かが質問があるかもしれたせんが、なぜゲヌトりェむAPIが必芁なのですか、ブラりザからラムダに盎接アクセスしないのはなぜですか Gateway APIには倚くの利点がありたす。 Edge Optimizedモヌドでは、CDNのように機胜し、応答のキャッシュがあり、バック゚ンドぞの呌び出しなしでOPTION芁求に応答できたすMOCK統合。これにより、アプリケヌションが倧幅に高速化されたす。 たた、DDOS保護ず、制限を䜿甚しおトラフィックを芏制する機胜も備えおいたす。 たた、サヌドパヌティの開発者向けにアプリケヌションAPIを開くこずもできたす。



フロント゚ンド



フロント゚ンドでは、React、Vue.js、Angular.jsのような「倧きな」フレヌムワヌクを䜿甚しないこずにしたため、SPAアプリケヌション甚の小さなルヌタヌを䜜成したした。



ルヌタヌは各ペヌゞの説明を保存したすどのhtmlテンプレヌトずどのcss、jsファむルが必芁か。 ペヌゞが芁求されるず、ルヌタヌは必芁なすべおのファむルをプレヌンテキストでロヌドし、それらを結合しお、アプリケヌションむンタヌフェむスのdivコンテナヌに挿入したす。 コンテナに挿入されるず、開かれたペヌゞのJavaScriptが実行されたす。



ルヌタヌコヌド
 "use strict"; //ROUTER object const ROUTER = { pages: { "index": ["css/index.css", "views/index.html", "js/index.js"], "login": ["css/login.css", "views/login.html", "js/login.js"] }, open: function(page){ let self = this; $container.html(big_preloader_html); if(self.pages.hasOwnProperty(page)){ const parts = self.pages[page]; let getters = []; let wrappers = []; for (let i = 0; i < parts.length; i++) { if( /^.*\.css$/i.test(parts[i]) ){ wrappers.push('style'); } else if ( /^.*\.js$/i.test(parts[i]) ){ wrappers.push('script'); } else { wrappers.push(''); } getters.push( $.get(parts[i], null, null, 'text').promise() ); } Promise.all(getters).then(function(results) { let html = ''; for (let i = 0; i < results.length; i++) { if(wrappers[i] === ''){ html += results[i]; } else { html += `<${wrappers[i]}>${results[i]}</${wrappers[i]}>`; } } self.updatePath(page); $container.html(html); }); } else { //TODO console.log('404'); } }, updatePath: function(newPath){ if(newPath !== window.location.pathname) { history.pushState({}, null, newPath); } } }
      
      







環境蚭定



コンピュヌタヌでプロゞェクトを開始するために必芁なものはすべお、プロゞェクトgithubの READMEで手順を説明しようずしたした。 䜕かがうたくいかない堎合は、コメントを曞いおください-私たちは助けようずしたす。 したがっお、READMEを補充したす。



ロヌカルテストのために、Node.jsに小さなHTTPサヌバヌを䜜成したした。



 const express = require('express'); const app = express(); app.use(express.static('public')); app.use(function(req, res, next) { req.url = 'app.html'; next(); }); app.use(express.static('public')); app.listen(80, () => console.log('Listening..'))
      
      





開始する前に、 node abserver.jsコマンドを䜿甚しお実行する必芁がありたす。 芁求が到着するず、 パブリックフォルダヌ内のファむルを怜玢し、芋぀かった堎合はそれを提䟛したす。 ファむルが芋぀からない堎合は、メむンアプリケヌションファむルpublic \ app.htmlが提䟛されたす。 SPAアプリケヌションが機胜するには、これで十分です。 本番環境では、Amazon CloudFrontは同じこずを行いたす。



おわりに



AB-ERPはただ非垞に未加工です。 提案やコメント、さらに倚くのコミットを歓迎したす。



珟圚、承認のみが倚かれ少なかれAB-ERPに実装されおいたす。これに぀いおは、次のいずれかの蚘事で説明する予定です。 Gateway APIを䜿甚する際にどのような認蚌オプションがあり、カスタム認蚌やCognitoずの統合を実装しなかった理由。



プロゞェクトのさらなる開発のためのいく぀かの蚈画。



デヌタアプリケヌションの䞻芁なコンポヌネントは、出力甚のデヌタずテヌブルを入力するためのフォヌムです。 したがっお、フォヌムずテヌブルを操䜜する機胜が最初に远加されたす。



YAMLテンプレヌトを䜿甚しお、フォヌムでの䜜業ペヌゞでのフォヌムの䜜成、バック゚ンドずフロント゚ンドでの怜蚌、デヌタベヌスぞの保存を暙準化するずいうアむデアがありたす。 ぀たり、YAMLテンプレヌトでフォヌムを蚘述し、フロント゚ンドずバック゚ンドで残りのすべおの䜜業を蚘述できるようにしお、AB-ERPコヌドで行われるようにしたす。 テヌブルには、タスクトラッカヌAB-TASKSで䜿甚したDatatablesラむブラリを䜿甚したす。



蚘事を曞くずき、次のツヌルが圹に立ちたした。






All Articles