あなたはPHP開発者です。 そうなんですね。 私の PHP への旅は、多くの PHP 開発者が完璧なプログラミング言語を求めて旅するような、普通の道ではありませんでした。 私は最初、Java開発者としてスタートし、およそ10年間その土地で暮らしました。 私は熱心な Java 開発者の一人で、PHP が話題にのぼると、エンタープライズ、スケーラビリティ、その他ナンセンスなことを言い始めます。
私は 5 年ほど前にソーシャルウェブのフロントエンドを必要とするオープンソースプロジェクトで働き始め、チームはそのサイトのプログラミング言語を選択する必要がありました。 私は Java や他のほとんどの言語を調査しましたが、多くの理由から PHP に落ち着きました。 プライドを捨ててPHPでコーディングするのは大変でしたが、そのプロジェクトで起きたことは奇跡としか言いようがありません。 私はこの言語に惚れ込み、自分のルーツであるJavaをほったらかしにしたまま、できる限り多くのプロジェクトでPHPを使うようになったのです。 この5年間、PHPは私にとても役に立ちましたが、私は、開発速度が速く、企業の支援を受けていて、パフォーマンスとスケーラビリティがあり、さらに開発者の強力なコミュニティを提供するプログラミング言語という聖杯を探し続けていたのです。 Node.js は、急速に成長し進化する言語でありながら、私のすべての要件を満たしていると思います。
最初に理解していただきたいのは、Node.js はヒップスター開発者やアーリーアダプターだけのものではないと言うことです。 今日、インターネット上で最もトラフィックの多い Web サイトのいくつかで使用されており、開発者の心をつかみ続けているのです。
Node.js は JavaScript##
Node.js で生産的になるためにまったく新しい言語を学ぶ必要があると思っているなら、それはおそらく間違っています。 ほとんどの開発者はすでに JavaScript に精通しており、それは Node.js でコーディングするときに使用される言語とセマンティクスです。 実際、Red Monkが最近発表した記事では、最も人気のある言語を決定するためにgithubプロジェクトを理解しようとし、JavaScriptが王者になっています。 上位3つの言語は次のとおりです。
- JavaScript
- Java
- PHP
JavaScriptの人気と業界全体での普及を考えると、もしまだ慣れていないなら、腰を据えて学び始める時期なのかもしれませんね。
Node.js が単に JavaScript を使用しているだけなら、Node.js とは一体何なのでしょうか。##
一言で言えば、Node.js はサーバー サイド アクティビティのためのプラットフォームです。 これは、Javascript プログラミング言語を使用し、npm モジュールとして利用可能な多数のライブラリがあります。 これらのnpmモジュールは、PHPの国から来た人ならComposerで満足できるかもしれないライブラリの依存関係だと考えてもよいでしょう。 実際、PHPのデフォルトの依存関係管理システム(Composer)は、公式サイトによるとNode.jsにインスパイアされたものだそうです。 もし、ちょっとした機能が必要で、すべてのコードを自分で書くのが面倒な場合は、探している機能をすでに提供している npm モジュールが利用可能です。
Node アプリケーションは通常、ノンブロッキング I/O および非同期イベントを利用して効率を最大化する必要がある場合に実装されます。 PHP 開発者が知っておくべきことの 1 つは、Node.js アプリケーションはシングルスレッドで実行されるということです。 しかし、バックエンドの Node.js コードは、ネットワークやファイルアクセスのような操作のために複数のスレッドを使用します。 これを考えると、Node はほぼリアルタイムのエクスペリエンスが求められるアプリケーションに最適です。
サンプル プロジェクトで始める##
このブログ記事の残りの部分では、PHP のバックグラウンドから Node.js でスピードアップする方法を紹介するつもりです。 これから書くサンプルアプリケーションは、Walmartの各店舗の場所を提供するシンプルなバックエンドサービスです。 この例でWalmartを選んだのは、簡単に言えば、すべての百貨店の聖杯だからです。
このブログ投稿の終わりまでに、人気のある MongoDB データベースで動作する Node.js を使用して、REST ベースの API をいかに迅速かつ簡単に作成できるかが分かると思います。 しかし、PHP で REST ベースのサービスを作成するさまざまなフレームワークや方法をすべて網羅するには、1 冊の本が必要であり、1 つのブログ投稿ではカバーしきれないのです。 そこで、人気上昇中のLaravelフレームワークを使うことを考えました。 しかし、それでもPHP開発者の4分の1程度にしか到達できないでしょう。 個人的には、私のお気に入りのフレームワークはCodeIgniterですが、急速に人気が落ちており、現在ではPHP開発者人口の8%未満しか占めていないのです。 Sitepoint は最近、まさにこのことを論じた記事を発表し、2014 年に最も有望なフレームワークを描いた次の図を提供しています。
フレームワークごとにデータベース接続を構成し REST サービスを作成する方法が大きく異なるため、ここでは PHP で自分のフレームワークにこれを行う方法を知っていると仮定し、代わりに Node.X にのみ焦点を当てます。
Node.jsアプリケーションの作成##
この記事の残りの部分では、StrongLoopのLoopBack APIフレームワークを使用して、Walmartロケーターアプリケーションを作成することになります。 おまけとして、OSXにNode.jsをインストールする方法を説明します。
Step 1: Installing Node.js##
Node.js をインストールする最も簡単な方法は、ほとんどのオペレーティング システムで利用できるバイナリ パッケージのうちの 1 つを使用する方法です。 ブラウザーを次の URL にポイントし、オペレーティング システムに適したものをダウンロードします:
http://nodejs.org/download/
このページをロードすると、次のように表示されます。 これにより、インストール プログラムがローカル コンピュータに保存されます。 ファイルがダウンロードされたら、ダウンロードした .pkg ファイルをダブルクリックしてインストール プログラムを開始し、インストール ダイアログが表示されます:
すべてのデフォルト設定を使用してインストール プロセスを完了し、最後に閉じるボタンをクリックして、インストールが正常に完了したらプログラムを終了します。 かなり簡単でしょう?
ステップ 2: NPM による LoopBack のインストール
さて、ローカル システムに Node.js をインストールしたので、StrongLoop が提供する LoopBack パッケージをインストールしたいと思います。 LoopBackはオープンソースのAPIフレームワークで、Node.jsで書かれたソフトウェアを書いてデプロイする方法を学び始めると、あなたの生活をより簡単にする機能を提供します。
LoopBackをインストールするために、Node.js配布物のコアに含まれるnpmコマンドを使用することにします。 NPM は、アプリケーションが依存するライブラリやモジュールをインストールするための公式パッケージ マネージャです。 この記事はPHP開発者向けに書かれているので、NPMモジュールについて考える簡単な方法は、Composerと関連付けることです。 Composerの依存システムを使うと、開発者はcomposer.jsonファイルで依存関係を指定することができるようになります。 パッケージが composer.json ファイルで定義されると、PHP 開発者は単に install コマンドを発行するだけでよく、次のようなコマンドになります。 また、依存関係をローカル システムで利用可能にするために、コマンド ラインからインストールすることもできます。 この後のステップで package.json ファイルについて詳しく説明しますので、まだ理解していなくても心配しないでください。
LoopBackをインストールするために、パッケージに必要なすべての依存関係をダウンロードおよびインストールするコマンドを1つ実行できます。 ターミナル ウィンドウを開き、次のコマンドを実行します。
$ npm install -g strongloop
Note: You may have to use sudo depending on your installation
What just happened? npm に strongloop パッケージをインストールしたいことを伝え、同時に -g
オプションを提供しました。 -g
オプションは、システム上の誰もが使用できるグローバルなパッケージとして、すべてのアプリケーションで使用できるようにします。 上記のコマンドを実行すると、NPM はパッケージだけでなく、必要な依存ファイルもダウンロードします。
Step 3: Creating our application##
LoopBack API を使用したアプリケーションの作成は、非常に簡単で直感的な方法です。 ターミナル ウィンドウを開き、次のコマンドを実行して locatewalmart
という新しいアプリケーションを作成します。
$ slc loopback _-----_ | | .--------------------------. |--(o)--| | Let's create a LoopBack | `---------´ | application! | ( _´U`_ ) '--------------------------' /___A___\ | ~ | __'.___.'__ ´ ` |° ´ Y ` Enter a directory name where to create the project: locatewalmart create locatewalmart/ info change the working directory to locatewalmart
slc
ユーティリティは、locatewalmart
という LoopBack ベースの新しいプロジェクトを作成し、プロジェクトを設定します。 アプリケーション名を聞かれたら、デフォルトのままで構いません。
What's the name of your application? locatewalmart
上記のコマンドを実行すると、プロジェクト用の新しいディレクトリが作成され、アプリケーション用に使用されるようになります。 cd コマンドでアプリケーション ディレクトリに移動します。
$ cd locatewalmart
アプリケーションを作成したので、ループバック用のデータソースとして MongoDB のサポートを追加します。
Step 4: DataSource#
MongoDBと通信するには、アプリケーションにデータソースを追加する必要があります。
$ slc loopback:datasource mymongo Enter the data-source name: mymongo Select the connector for mymongo:PostgreSQL (supported by StrongLoop)Oracle (supported by StrongLoop)Microsoft SQL (supported by StrongLoop)❯ MongoDB (supported by StrongLoop)SOAP webservices (supported by StrongLoop)REST services (supported by StrongLoop)Neo4j (provided by community)(Move up and down to reveal more choices)
Step 5: 実際のデータソースを指定する ###
MongoDBと通信するために、データソースを実際のMongoDBインスタンスに指定する必要があります。 LoopBackでは、アプリケーションのroot/server
ディレクトリにあるdatasource.json
ファイルにすべてのデータソースの設定を定義しています。 このファイルを開いて、次のコードのように MongoDB 用のデータソースを追加します:
{ "db": { "name": "db", "connector": "memory" }, "mymongo": { "name": "mymongo", "connector": "mongodb" "url": "mongodb://localhost:27017/locatewalmart" }}
Note: 必ず MongoDB データベースの正しい接続 URL を指定してください。 この例では、ローカルに作成した locatewalmart というデータベースをデータソースに使用します。
データベースを定義したところで、いくつか追加しなければならないことがあります。 まず最初に、このアプリケーションが loopback-connector-mongodb
パッケージに依存していることを指定する必要があります。 依存関係を指定するには、PHP の composer.json
ファイルを編集するのと同じように package.json ファイルを変更します。 アプリケーションのルートディレクトリにある package.json
ファイルを開き、依存関係のセクションに loopback-connector-mongodb
を追加します。 その後、npm install.
Alternatively you can just run:
$ npm install loopback-connector-mongodb --save
This will auto update the package.json
.This can’t be added the dependency section. セクションは次のようになります:
"dependencies": { "compression": "^1.0.3", "errorhandler": "^1.1.1", "loopback": "^2.0.0", "loopback-boot": "^2.0.0", "loopback-connector-mongodb": "^1.4.1", "loopback-datasource-juggler": "^2.0.0", "serve-favicon": "^2.0.1" }
Step 6: MongoDB にデータをインポートする###
データソースの設定ができたので、データセットを MongoDB データベースにロードする必要があります。 これは次の URL で取得できます:
https://dl.dropboxusercontent.com/u/72466829/walmart.json
データセットをダウンロードしたら、次のように mongoimport コマンドを使ってデータベースにインポートします:
$ mongoimport --jsonArray -d locatewalmart -c store --type json --file walmart.json -h yourMongoHost --port yourMongoPort -u yourMongoUsername -p yourMongoPassword
以下の結果が表示されるはずです。
connected to: 127.0.0.12014-08-17T13:07:26.301-0400 check 9 31762014-08-17T13:07:26.305-0400 imported 3176 objects
Step 7: Store モデルの作成 ###
モデルは、MVC フレームワークを使用している場合、PHP ランドでモデルについて考えるのと同じ用語で考えることができます。 これは、オブジェクトの表現であり、この場合はWalmartストアです。 LoopBackでは、コマンドラインからモデルオブジェクトを作成する便利な方法を提供しています。 ターミナルウィンドウを開き、プロジェクトフォルダに移動して、次のコマンドを実行してください:
$ slc loopback:model
これにより、モデルを定義するための対話型セッションが開始されます。 最初に尋ねられるのは、モデルを関連付けたいデータ ソースです。 ここでは先ほど作成した mymongo データソースを選択します。 次にモデルの名前を聞かれます。
Enter the model name: store Select the data-source to attach store to:db (memory)❯ mymongo (mongodb) Expose store via the REST API? Yes Custom plural form (used to build REST URL):
Enter キーを押すと、store モデルのプロパティを指定するプロンプトが表示されます。 これは、PHP のクラスで定義する var (s) と考えることができます。
Enter an empty property name when done. Property name:
追加したいプロパティは、店舗のタイプ、オープン日、緯度と経度です。
Property name: opendate invoke loopback:property
エンターキーを押すと、指定した各プロパティのデータ タイプを提供するか尋ねられることになります。 最初の項目はopendateとなり、それが日付型であることを選択したいと思います。 dateを選択してエンターキーを押します。
Property type: string number boolean object array❯ date buffer geopoint (other)
次に、スキーマ検証のためにこのプロパティを必須とするかどうかを聞かれます。 ここでは「はい」と入力します。
Required? (y/N) : y
次に、残りの各プロパティのデータ型について質問されます。
Property name: type_store invoke loopback:property Property type: (Use arrow keys)❯ string number boolean object array date buffer geopoint (other) Required? (y/N) : yLet's add another store property.Enter an empty property name when done. Property name: latitude invoke loopback:property Property type: (Use arrow keys)❯ string number boolean object array date buffer geopoint (other) Required? (y/N) : yLet's add another store property.Enter an empty property name when done. Property name: longitude invoke loopback:property Property type: (Use arrow keys)❯ string number boolean object array date buffer geopoint (other) Required? (y/N) : y
“yes” と入力して Enter キーを押します。
おめでとうございます!Node.js と連携して LoopBack を使用して、最初のモデル オブジェクトを作成しました。 実際に何が作成されたかを見るには、アプリケーションディレクトリのroot/common/models
ディレクトリにあるstore.json
ファイルを開いてください。 以下のように表示される stores エントリを探します:
{ "name": "store", "base": "PersistedModel", "properties": { "opendate": { "type": "date", "required": true }, "type_store": { "type": "string", "required": true }, "latitude": { "type": "string", "required": true }, "longitude": { "type": "string", "required": true } }, "validations": , "relations": {}, "acls": , "methods": }
ご覧のように、モデルが作成され、定義したプロパティがストアモデルに割り当てられています。 public フィールドは、REST Web サービスを介してこのモデルを世界に公開することを指定します。
モデルのデータ ソースへのマッピングは、アプリのルート/サーバー フォルダー下の model-config.json
で定義されます。 データソース フィールドは、このモデルが CRUD 操作に使用するデータソースを指定します。
"store": { "dataSource": "mymongo", "public": true }
Step 8: REST ベース API##
Guess what? あなたは、Node.js を使用して、最初の REST ベースの Web サービスを作成したところです。 それほど悪くはないでしょう。 今作成したアプリケーションをブラウザで表示して、確認してみましょう。 次のURLにアクセスします:
http://0.0.0.0:3000/api/stores/
次の画像に示すように、データベースにインポートしたすべてのウォルマートストアのJSON表現が表示されます:
StrongLoopエクスプローラを使って##
さて、素晴らしいですね。 データベース内のWalmartストアをすべて返すRESTエンドポイントはありますが、データを操作したり、すべてのCRUD操作が機能しているかどうかを確認するための管理インターフェースがないため、まだ少し物足りないような気がします。 幸いStrongLoopは便利なブラウザを提供しており、アプリケーションが持つ全てのエンドポイントを探索することができます。 これを試すには、ブラウザを開いて以下のURLにアクセスします:
http://0.0.0.0:3000/explorer/
エクスプローラページをロードしたら、stores
APIを展開してモデルオブジェクトに許可されている全ての利用可能な操作を確認します。 これは次のイメージに示されています。
Explorer でできることの例として、/stores/findOne
API を展開して、Try it out!
リンクをクリックすると、次のイメージに示すようにデータベースに照会して 1 つのレコードが返されます。
Taking things a bit further by adding a map representation##
Awesome, we have a REST based endpoint that will return a list of all of the Walmart stores in our database.
Step 1: Create the public directory##
By default, as specified in the app.js file of the project, any files in the public directory located in the applications root directory will be served to the requestor.StrongLoop によるフルアプリケーション開発の速度をさらに示すために、すべての Walmart store のピンがあるマップを含むレスポンシブ フロントエンドを構築しましょう。 しかし、このディレクトリはデフォルトでは存在しない可能性があるため、作成する必要があります。 ターミナルを開き、アプリケーションのルート ディレクトリに移動して、次のコマンドを発行します。
$ mkdir public
ステップ 2: レスポンシブ マップの作成###
次に行う必要があることは、データの優れた表現を作成することです。 すべての店舗の緯度と経度があるので、ユーザーがドラッグして移動したり、拡大/縮小したりできる地図で、このコンテンツを表現できたら素晴らしいと思います。 この作業は、既存のライブラリを活用すれば、実は意外と簡単です。 このレスポンシブ ビューを作成すると、結果は次のようになります。
さらに、次の画像のように、ユーザーはマップの非常に詳細なレベルにズームインして、最も近い Walmart を見ることができます。 また、マップを作成し、マップ上にピン (マーカー) を配置するために、人気のある Leaflet ライブラリを使用します。
このマップを作成するには、public ディレクトリに locatewalmart.html
という名前の新しいファイルを作成し、次の JavaScript コードを追加します:
<!doctype html><html lang="en"><head> <title>Walmart Stores</title> <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.5.1/leaflet.css" /><!--> <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.5.1/leaflet.ie.css" /><!--><script src="https://code.jquery.com/jquery-2.0.0.min.js"></script><link href='http://fonts.googleapis.com/css?family=oswald' rel='stylesheet' type='text/css'><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /><style type="text/css">body { padding: 0; margin: 0;}html, body, #map { height: 100%; font-family: 'oswald';}.leaflet-container .leaflet-control-zoom { margin-left: 13px; margin-top: 70px;}#map { z-index: 1;}#title { z-index: 2; position: absolute; left: 10px; }</style></head><body><h1>Walmart Stores</h1><div></div><script src="http://cdn.leafletjs.com/leaflet-0.5.1/leaflet.js"></script><script>center = new L.LatLng(39.83, -98.58);zoom = 5;var map = L.map('map').setView(center, zoom);var markerLayerGroup = L.layerGroup().addTo(map);L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {maxZoom: 18,attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'}).addTo(map);function getPins(e){url = "http://0.0.0.0:3000/api/stores";$.get(url, pinTheMap, "json")}function pinTheMap(data){//clear the current pinsmap.removeLayer(markerLayerGroup);//add the new pinsvar markerArray = ;var lastNumber = 0;for (var i = 0; i < data.length; i++){store = data;if(store.latitude.length > 0 && store.longitude.length>0) {markerArray.push(L.marker());}}markerLayerGroup = L.layerGroup(markerArray).addTo(map);}map.whenReady(getPins)</script></body></html>
ご覧のように、コードは単なる標準の HTML と JavaScript です。 興味深いのは getPins(e) 関数で、このブログの記事で以前に作成した API に REST 呼び出しを行っているところです。 そして、各店舗に対して繰り返し処理を行い、各店舗の緯度と経度を指定してピンを作成します。 このブログ記事では、米国内の Walmart の店舗のリストを返す REST ベースの Web サービスを作成する方法を紹介しました。 Loopback を使用して Web サービスを作成した後、データのフロントエンド表現を追加しました。 わずかな作業で、現在使用している言語よりもはるかに速く、完全に機能するアプリケーションを開発することができました。 また、Node.jsとPHPの類似点についても議論しました。 PHPは今でも素晴らしい言語だと思いますが、個人的には、ライブラリの豊富なエコシステムとアプリケーションの作成速度を考えると、Node.jsは次に学ぶべき素晴らしい言語であると思います。
Node.js と PHP を比較する際に参照できる簡単な表を用意しました。
特徴 |
PHP |
Node.js |
|
Great IDE |
Yes, multi choice with IntelliJ, Zend Studio, Netbeans, etc |
Yes, Eclipse、Visual Studio、Codenvyなど複数選択可 |
|
Dependency Management |
Composer, PEAR |
NPM |
|
Enterprise Ready |
はい。 |
はい |
|
ライブラリの大きなエコシステム |
はい。 しかし、時々見つけるのが難しい |
はい |
|
共通フレームワーク |
CodeIgniter, CakePHP, Laravel, etc |
Express, Meteor.Laravel, CakePHP |
共通フレームワーク |
データベース対応 |
有 |
||
非対応ブロック IO |
No |
Yes |
|
Testing フレームワーク |
Yes |
Yes |
|
Real-IDIタイムアプリケーション |
はい。 Apache WebSocket などの追加プロセスあり。 |
あり |
|
内蔵のWebサーバ |
なし。 ほとんどの人は Apache と組み合わせて使用しています |
はい |
- Node.NET API でAPIを開発する準備ができている。jsでAPIを開発し、データに接続する準備はできましたか? Node.js LoopBack フレームワークをチェックしてみてください。 ローカルでもお気に入りのクラウドでも、簡単な npm インストールで始められるようにしました。