Node jsによるWeb APIの高速シミュレーション

8614 ワード

Web APIは、ネットワークを介して呼び出されるAPIインタフェースであっても、具体的なプログラミング言語とは無関係である.現在一般的なのは、標準的なHTTP GET/POSTリクエストにより、サーバから応答するリソースまたはサービスを取得し、サーバは呼び出しの結果内容を返し、一般的にxml形式またはjson形式のデータ(現在はjsonのより多く使用されている)である.
Appを開発する際、just in mindなどのツールを使用するなど、一般的なプロトタイプが設計された後、サーバとインタラクティブなインタフェースドキュメントを設計します.一般的に、Appの開発進捗(特にプロトタイプ)はサーバの開発進捗よりも速い.App静的プロトタイプの開発が完了してから、サーバがすべてのインタラクティブインタフェースを実現するまでの間、私たちはもちろん暇ではありません.この場合、HTTPサーバをローカルでシミュレートすることで、Appの「動的化」開発を継続できます.
Javascriptに詳しいので、node jsを簡単に見てから、ローカルのHTTPサーバを開発し、さまざまなインタラクティブなインタフェースを提供します.ここでは、どのようにして一歩一歩実現したのかを記録します.
一歩一歩HTTPサーバーを実現
例を挙げると、3つのインタフェース(いくつかにかかわらず、原理は同じ)が作成され、以下のようになります.
   
/sample_app/focus_pic

    
/sample_app/article_list

    
/sample_app/article_detail

サーバを次のモジュールに分割できます.
  • 入口-app.js、全体的な管理サーバ.一般的に起動サーバ
  • serverモジュール-server.jsは、サーバの構成とリクエストの転送を担当します.サーバが傍受するポート、要求ログの記録、要求を特定の処理関数などの
  • に転送する.
  • routerモジュール-router.jsは、その名の通り、リクエストのルーティング機能を担当します.例えば、ここでは、異なる要求アドレスを異なる関数処理に転送することができる.
  • request handlersモジュール-request_handler.jsは,各リクエストに対して処理する関数をこのモジュールに定義する.
  • response templateモジュールは、Web APIサービスを提供するHTTPサーバを素早くシミュレートするだけなので、本当に戻ってきた内容はテンプレートに書けばいいです.

  • 実は3つのインタフェースのルーティング(異なるリクエストを対応する処理関数に転送)は当然routerモジュールで処理すべきであるが,インタフェースごとの処理ロジックは同じであるため,返す内容が異なるだけでルーティングロジックをrequest handlersモジュールに転送した.具体的にどのように書くかは、実際の状況に応じて調整することができますが、この中では一つの考え方を提供しているだけです.
    文字を見るだけでは難しいので、具体的なコードを見てみましょう.server.js
    /** * Created by FIMH on 2016/05/05. */
    var http = require('http');
    var url = require('url');
    
    function start(route, handle) {
        function onRequest(request, response) {
            //       
            var parsedUrl = url.parse(request.url);
            var pathname = parsedUrl.pathname;
    
            console.log('Request for ' + pathname + ' received.');
    
            route(handle, parsedUrl, request, response);
        }
    
        http.createServer(onRequest).listen(9999);
        console.log('Server has started.');
    }
    
    exports.start = start;

    主にHTTPサーバが傍受するポート-9999が構成され、log情報が印刷され、要求がrouterモジュールに転送されて処理されることがわかります.
    router.js
    /** * Created by FIMH on 2016/05/05. */
    //        ,       
    function route(handler, parsedUrl, request, response) {
        var pathname = parsedUrl.pathname;
        console.log('About to route a request for ' + pathname);
    
        //     favicon.ico
        if (!pathname.indexOf('/favicon.ico')) {
            return;
        }
    
        //               ,     handle       
        handler(parsedUrl, request, response);
    }
    
    exports.route = route;

    ここでは主にfaviconを遮断しましたicoファイルへのアクセスは、このファイルが何なのかについて、自分で検索することができます.前述したように、このsampleでは、各インタフェースの処理ロジックが同じであるため、返される内容が異なるだけで、ルーティングロジックをrequest handlersモジュールに転送しました.
    本当の処理ロジックは次のモジュールでrequests_handlers.js
    /** *       。 */
    function handleRequests(parsedUrl, request, response) {
        //      querystring
        //var queryStringUtil = require('querystring');
        //var queryString = parsedUrl.query;
        //var queryStringResultObject = queryStringUtil.parse(queryString);
    
        var pathname = parsedUrl.pathname;
    
        //        
    }
    
    exports.handleRequests = handleRequests;

    ここでは、リクエスト処理のエントリ関数を1つだけ貼り付けました.ここで私は一度再構築しましたが、最初の処理ロジックは大体次のようになっています.
        var templateName;
        var innerHtml;
        if (pathname == '/sample_app/focus_pic') { templateName = 'focus_pic'; } else if (pathname == '/sample_app/article_list') { templateName = 'article_list'; } else if (pathname == '/sample_app/article_detail') { templateName = 'article_detail'; innerHtml = 'article'; }
    
        if (templateName) { handleValidRequest(request, response, templateName, innerHtml); } else { handleErrorOutput(request, response, 400, 'Invalid request url!'); }

    ここでは3つのリクエストしかないので、見ているとまだ明らかではありませんが、比較的多いとif...elseが書くのが煩わしいので、cocos 2 d-js,egretのようなjs言語のプロジェクトがjsonファイルをプロジェクトのプロファイルとして使用していることを思い出し、世代コードを順次簡略化し、柔軟性を高めています.
    この場合、プロジェクトのプロファイルを定義することができます.ここではappProperties.jsonと名付けられています.内容は次のとおりです.
    {
      "route": { "/sample_app/focus_pic": { "template": "focus_pic" }, "/sample_app/article_list": { "template": "article_list" }, "/sample_app/article_detail": { "template": "article_detail", "inner_html": "article" } } }

    次に、前述のモジュール-requests_を変更します.handlers.jsは、まずグローバル変数var routeObj;を定義し、関数handleRequestsでこのように処理する.
    //   route    
        if (!routeObj) {
            var fs = require('fs');
            var propertiesPath = './appProperties.json';
            var propertiesData = fs.readFileSync(propertiesPath, 'utf-8');
    
            routeObj = JSON.parse(propertiesData);
        }
    
        var templateObj = routeObj['route'][pathname];
        if (templateObj) {
            handleValidRequest(request, response, templateObj['template'], templateObj['inner_html']);
        } else {
            handleErrorOutput(request, response, 400, 'Invalid request url!');
        }

    再構築後、インタフェースがいくつであっても、処理されたコードはこれらの行です.再構成前の方法では、インタフェースを追加するたびにelse ifを追加する必要があります.アルゴリズムの複雑さの概念を比較すると,再構成前はO(n)であり,再構成後はO(1)である.
    response templateモジュールの処理については、ここではコードを貼りません.主にnode jsを使用してテンプレートファイルを同期または非同期で読み込み、jsonオブジェクトのシーケンス化、編集、逆シーケンス化を行います.興味があればsample全体のソースコードを見ることができます.文章の下部を参照してください.
    概要とソースコード
    従来の方法を使用する場合は、apacheなどのhttpサーバとphpなどの言語処理モジュールをインストールする必要があります.node jsを使用した後、node実行時に残りのhttpサーバをインストールし、解析、処理、戻りを要求するなど、すべてjsを使用して作成すればよいし、書くコードの量も少ない.
    プロジェクト全体のコードをgithubに置きました.詳しくはnodejs_を参照してください.sample_app