{
    "componentChunkName": "component---src-templates-blog-post-jsx",
    "path": "/post/nextengine-api-client-with-nodejs/",
    "result": {"data":{"site":{"siteMetadata":{"title":"WEB EGG","author":"Leko - CTO at Yuimedi"}},"markdownRemark":{"id":"320996d0-c6a3-561e-bcc1-c41095a558eb","excerpt":"こんにちは。 この記事はHamee Advent Calendar 2016の25日目の記事です。 Hameeカレンダーの大トリを努めます。れこです。 今回は敬虔たるネクストエンジン(以下NEと略します)開発者の皆様へクリスマスプレゼントです。 NEのNodejs版API…","html":"<p>こんにちは。<br>\nこの記事は<a href=\"http://qiita.com/advent-calendar/2016/hamee\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Hamee Advent Calendar 2016</a>の25日目の記事です。</p>\n<p>Hameeカレンダーの大トリを努めます。れこです。<br>\n今回は敬虔たる<a href=\"http://next-engine.net/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">ネクストエンジン</a>(以下NEと略します)開発者の皆様へクリスマスプレゼントです。<br>\nNEのNodejs版APIクライアントを作成したので紹介させていただきたいと思います。</p>\n<!--more-->\n<h2 id=\"はじめに\" style=\"position:relative;\"><a href=\"#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB\" aria-label=\"はじめに permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>はじめに</h2>\n<p>作ったものはこちらです。<br>\nインストール方法、詳しい使い方などもこのリポジトリを参照してください。</p>\n<blockquote>\n<p><a href=\"https://github.com/Leko/node-nextengine\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Leko/node-nextengine: Nextengine API for Nodejs</a></p>\n</blockquote>\n<p>このクライアント、 <strong>非公式</strong> です。<br>\n何度でも書きます。 <strong>非公式</strong> です。<br>\nとある案件でNodejs使ったのですが、NE APIのクライアントが無かったので勝手にドッグフーディングしつつ作って公開したという感じです。</p>\n<p>感覚的にはGoogleAnalyticsチームが公開している非公式プロダクト<a href=\"https://github.com/googleanalytics/autotrack\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">autotrack</a>なんかと近いかな、と思っています。<br>\nメンテナンスは私個人として行っていきますので、何かあればPRやIssueにお願いします。</p>\n<h2 id=\"解消しようとした問題たち\" style=\"position:relative;\"><a href=\"#%E8%A7%A3%E6%B6%88%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%9F%E5%95%8F%E9%A1%8C%E3%81%9F%E3%81%A1\" aria-label=\"解消しようとした問題たち permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>解消しようとした問題たち</h2>\n<p>NE APIを利用していて、既存のSDKたちを見ていて思った問題点がこれら</p>\n<ul>\n<li>プログラム中にv1という文字が入るのがキモい</li>\n<li>SQLっぽいクエリパラメータが扱いにくい</li>\n<li>非同期アップロードが扱いにくい</li>\n<li>アクセストークンの取扱いが面倒</li>\n<li>認可処理も癖があるのでpassportのStrategyも作って隠蔽したい</li>\n</ul>\n<h2 id=\"プログラム中にv1という文字が入るのがキモい\" style=\"position:relative;\"><a href=\"#%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E4%B8%AD%E3%81%ABv1%E3%81%A8%E3%81%84%E3%81%86%E6%96%87%E5%AD%97%E3%81%8C%E5%85%A5%E3%82%8B%E3%81%AE%E3%81%8C%E3%82%AD%E3%83%A2%E3%81%84\" aria-label=\"プログラム中にv1という文字が入るのがキモい permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>プログラム中にv1という文字が入るのがキモい</h2>\n<p><a href=\"http://api.next-e.jp/request_url.php\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">NE APIのリクエストURL一覧</a>を見るとわかると思いますが、<br>\n<code>/api_v1_receiveorder_base/count</code>のような感じでパスの途中に<code>v1</code>と思い切りバージョン番号が入っています。<br>\nもしアプデかかったらどうするんだろう。一括置換でもするのだろうか。と不安があります。</p>\n<p>例えばChatWorkのように<code>https://api.chatwork.com/v1</code>と、先頭に入ってくれていればまだ救いようがあるのですが、パスの途中は辛い。<br>\n同じく非公式の<a href=\"https://github.com/infinity-octaver/ne_api\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">NE API Ruby版SDK</a>はおそらく同じことを感じたのか回避されています。</p>\n<p>ということでパスを隠蔽してコード内にバージョン番号が混じらないようにしました。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">const</span> Nextengine <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'next-engine'</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> ReceiveOrder <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'next-engine/Entity'</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">const</span> client <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Nextengine</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  clientId<span class=\"token operator\">:</span> <span class=\"token string\">'XXXXXXXXXX'</span><span class=\"token punctuation\">,</span>\n  clientSecret<span class=\"token operator\">:</span> <span class=\"token string\">'XXXXXXXXXX'</span><span class=\"token punctuation\">,</span>\n  accessToken<span class=\"token operator\">:</span> <span class=\"token string\">'XXXXXXXXXX'</span><span class=\"token punctuation\">,</span>\n  refreshToken<span class=\"token operator\">:</span> <span class=\"token string\">'XXXXXXXXXX'</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\nclient<span class=\"token punctuation\">.</span><span class=\"token function\">query</span><span class=\"token punctuation\">(</span>ReceiveOrder<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">count</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">count</span> <span class=\"token operator\">=></span> console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>count<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>ゴリ押しですが、コード内にパスがハードコートされていて、バージョンアップが来たときに追従できないよりはマシだと思っています。<br>\nこれで仮にパスが変わってもライブラリ内部で吸収が可能です。</p>\n<h2 id=\"sqlっぽいクエリパラメータが扱いにくい\" style=\"position:relative;\"><a href=\"#sql%E3%81%A3%E3%81%BD%E3%81%84%E3%82%AF%E3%82%A8%E3%83%AA%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%81%8C%E6%89%B1%E3%81%84%E3%81%AB%E3%81%8F%E3%81%84\" aria-label=\"sqlっぽいクエリパラメータが扱いにくい permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>SQLっぽいクエリパラメータが扱いにくい</h2>\n<p><a href=\"http://api.next-e.jp/operator_compare.php\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">NE APIの比較演算子一覧</a>を見てもらえばわかると思いますが、<br>\n割と柔軟に検索条件が組めるようになっています。<br>\nただし形式がSQLっぽい感じのフォーマットを矯正されるので結構扱いにくいと感じています。</p>\n<p>SQLっぽいものが書けるのであれば、パラメータを頑張って作るのではなく、クエリビルダっぽいDSLで書けたら良いのでは。<br>\nと思って作ってみました。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> Goods <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'next-engine/Entity'</span><span class=\"token punctuation\">)</span>\nclient<span class=\"token punctuation\">.</span><span class=\"token function\">query</span><span class=\"token punctuation\">(</span>Goods<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">where</span><span class=\"token punctuation\">(</span><span class=\"token string\">'goods_id'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'abc'</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">limit</span><span class=\"token punctuation\">(</span><span class=\"token number\">500</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">offset</span><span class=\"token punctuation\">(</span><span class=\"token number\">350</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">results</span> <span class=\"token operator\">=></span> console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>results<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>まだ機能は少ない（<code>where</code>, <code>limit</code>, <code>offset</code>くらい）ですが、もしメソッドを足すとしたら<a href=\"http://knexjs.org/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">knex</a>というクエリビルダのライブラリのAPIに寄せていこうと思っています。</p>\n<h2 id=\"非同期アップロードが扱いにくい\" style=\"position:relative;\"><a href=\"#%E9%9D%9E%E5%90%8C%E6%9C%9F%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%8C%E6%89%B1%E3%81%84%E3%81%AB%E3%81%8F%E3%81%84\" aria-label=\"非同期アップロードが扱いにくい permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>非同期アップロードが扱いにくい</h2>\n<ol>\n<li>アップロードAPI叩く、キューIDが帰ってくる</li>\n<li>キューIDを使ってキュー監視API叩く</li>\n<li>キューが成功/失敗相当のステータスになっていればになっていれば処理完了</li>\n</ol>\n<p>という操作が何箇所かあるのですが、扱いにくい。<br>\nですがjsにはPromiseという非同期処理を抽象化する機構が用意されているので、</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">const</span> zlib <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'zlib'</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> promisify <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'es6-promisify'</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> stringify <span class=\"token operator\">=</span> <span class=\"token function\">promisify</span><span class=\"token punctuation\">(</span><span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'csv-stringify'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> deflate <span class=\"token operator\">=</span> <span class=\"token function\">promisify</span><span class=\"token punctuation\">(</span>zlib<span class=\"token punctuation\">.</span>deflate<span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> UploadQueue <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'next-engine/Entity'</span><span class=\"token punctuation\">)</span>\n\ninput <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span>\n  <span class=\"token punctuation\">[</span><span class=\"token string\">'syohin_code'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'jan_code'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">[</span> <span class=\"token string\">'abc'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'1234567890'</span> <span class=\"token punctuation\">]</span>\n<span class=\"token punctuation\">]</span>\n<span class=\"token function\">stringify</span><span class=\"token punctuation\">(</span>input<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">csv</span> <span class=\"token operator\">=></span> <span class=\"token function\">deflate</span><span class=\"token punctuation\">(</span>csv<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">gz</span> <span class=\"token operator\">=></span> client<span class=\"token punctuation\">.</span><span class=\"token function\">uploadAndWaitFor</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> data_type<span class=\"token operator\">:</span> <span class=\"token string\">'gz'</span><span class=\"token punctuation\">,</span> data<span class=\"token operator\">:</span> gz <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Imported!'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>のように、<code>uploadAndWaitFor</code>というメソッドを用意して「アップロードして（ポーリングしながら結果を）待つ」処理を非同期化してみました。<br>\nこれ使うと楽ではあるのですが、プロセスを長いこと握ることになるので、ワーカージョブやバッチでしか使用を推奨できません。</p>\n<p>それ以外の場合は<code>upload</code>メソッドと<code>waitFor</code>メソッドをそれぞれ別個に使用し、アップロードとキューの監視を別プロセスに分けるようにも作れます。</p>\n<h2 id=\"アクセストークンの取扱いが面倒\" style=\"position:relative;\"><a href=\"#%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%81%AE%E5%8F%96%E6%89%B1%E3%81%84%E3%81%8C%E9%9D%A2%E5%80%92\" aria-label=\"アクセストークンの取扱いが面倒 permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>アクセストークンの取扱いが面倒</h2>\n<p>NE APIでは、レスポンスに常にアクセストークンが含まれており、 <strong>これが不定期に勝手に更新されます。</strong><br>\nよく意味がわからないかもしれませんが、要はよくあるOAuth2風に</p>\n<ol>\n<li>APIを叩いたら「アクセストークンの期限が切れたよ」的なエラーが返ってくる</li>\n<li>リフレッシュトークンを使ってアクセストークンをリフレッシュするAPIを叩く</li>\n<li>返ってきた認可情報で処理を継続する</li>\n</ol>\n<p>という形式ではなく、「いつ変わるかわならないアクセストークンをAPIリクエスト１回ごとに考慮する」必要があります。<br>\nこればかりは要件や実装によって保持・更新する方法が変わると思うので抽象化できませんでした。</p>\n<p>とりあえず、<code>new Nextengine</code>したインスタンスは<code>accessToken</code>, <code>refreshToken</code>プロパティ経由で最新のアクセストークン・リフレッシュトークンを入手できます。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> Goods <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'next-engine/Entity'</span><span class=\"token punctuation\">)</span>\nclient<span class=\"token punctuation\">.</span><span class=\"token function\">query</span><span class=\"token punctuation\">(</span>Goods<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">where</span><span class=\"token punctuation\">(</span><span class=\"token string\">'goods_id'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'abc'</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">limit</span><span class=\"token punctuation\">(</span><span class=\"token number\">500</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">offset</span><span class=\"token punctuation\">(</span><span class=\"token number\">350</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">results</span> <span class=\"token operator\">=></span> console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>results<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>もしくは、内部で使用しているConnectionクラスを拡張することでも対応可能です。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">const</span> Nextengine <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'next-engine'</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> Connection <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'next-engine/lib/Connection'</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">MyConnection</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">Connection</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">handleResponse</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">res</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">super</span><span class=\"token punctuation\">(</span>res<span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">json</span> <span class=\"token operator\">=></span> json<span class=\"token punctuation\">)</span> <span class=\"token comment\">// 何か拡張する</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">MyNextengine</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">Nextengine</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">getConnection</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">accessToken<span class=\"token punctuation\">,</span> refreshToken</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">MyConnection</span><span class=\"token punctuation\">(</span>accessToken<span class=\"token punctuation\">,</span> refreshToken<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>他にもPROXY噛ませたりと共通で行いたい処理などがあれば上記方法で拡張可能です。</p>\n<p>ちなみにHTTPクライアントは<a href=\"https://github.com/bitinn/node-fetch\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">node-fetch</a>を(isomorphic-fetch経由で)使用しています。<br>\n最悪、上記方法で無理やり差し替えも可能です。</p>\n<p>例えば、<code>NextEngine.on('refresh', ({ accessToken, refreshToken }) => ...)</code>みたいなAPI設計も可能かなーと思ったんですが、<br>\nイベントベースにするとトリッキーさが増してしまうのであえて作らないという方向に倒しました。</p>\n<h2 id=\"認可処理も癖があるのでpassportのstrategyも作って隠蔽したい\" style=\"position:relative;\"><a href=\"#%E8%AA%8D%E5%8F%AF%E5%87%A6%E7%90%86%E3%82%82%E7%99%96%E3%81%8C%E3%81%82%E3%82%8B%E3%81%AE%E3%81%A7passport%E3%81%AEstrategy%E3%82%82%E4%BD%9C%E3%81%A3%E3%81%A6%E9%9A%A0%E8%94%BD%E3%81%97%E3%81%9F%E3%81%84\" aria-label=\"認可処理も癖があるのでpassportのstrategyも作って隠蔽したい permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>認可処理も癖があるのでpassportのStrategyも作って隠蔽したい</h2>\n<p><a href=\"http://api.next-e.jp/auth.php\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">ネクストエンジンAPIの認証について</a>のページに認証フローが書かれているのですが、<br>\n何度見したか覚えてないとすら感じる不思議なフローです。</p>\n<p>この認証フローをアプリごとにスクラッチするのは骨が折れるので、<br>\nNodejsアプリの認証レイヤを抽象化する<a href=\"http://passportjs.org/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Passport</a>というライブラリに対応したストラテジーを作成しました。</p>\n<blockquote>\n<p><a href=\"https://github.com/Leko/passport-nextengine\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Leko/passport-nextengine: Nextengine authentication strategy for Passport and Node.js</a></p>\n</blockquote>\n<p>これで認証方法の特殊さを気にすることなく、OAuth2のストラテジー（Githubとか）の感覚で扱えるようになります。</p>\n<h2 id=\"まとめ\" style=\"position:relative;\"><a href=\"#%E3%81%BE%E3%81%A8%E3%82%81\" aria-label=\"まとめ permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>まとめ</h2>\n<p>そもそもなんで作ったのかという話ですが、<br>\n「Nodejsの公式SDK出てないからNodeで作る選択肢がない」をぶち壊そうとしたというのが根幹にあります。<br>\nその次に私自身が(Node)jsが好きだから手に馴染んでいる言語で書けるように作っておいたという感じです。</p>\n<p>ライブラリは機能はもちろんですが、ガワの設計が何より大事だと思っているので、自分が使いたいAPIクライアントを作りました。<br>\n一度ベースを作ってしまえば必要に応じてリトライの考慮入れたりなんだりと強化していけるので、今後に期待していただければと思います。</p>\n<p>繰り返しますが、 <strong>非公式です</strong> 。<br>\n何かあればリポジトリのIssueにお願いします。もしくはPRください！</p>\n<h2 id=\"さいごに\" style=\"position:relative;\"><a href=\"#%E3%81%95%E3%81%84%E3%81%94%E3%81%AB\" aria-label=\"さいごに permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>さいごに</h2>\n<p>ネクストエンジンには Developer Network (略してDevNet）という開発者向けコミュニティサイトがあります。<br>\nここには 開発ガイド 、 APIリファレンス 、チュートリアルなど開発の役に立つ情報が盛りだくさんです。<br>\nまた開発者同士でディスカッションする コミュニティ もあります。<br>\nわからないことがあれば こちら に質問を投稿してください。</p>\n<p>ネクストエンジン Developer Networkwork<br>\n<a href=\"https://developer.next-engine.com/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://developer.next-engine.com/</a></p>","timeToRead":10,"frontmatter":{"title":"ネクストエンジンAPIのNodejs版クライアント作った","tags":["Nodejs"],"date":"December 24, 2016","featuredImage":null}}},"pageContext":{"slug":"/nextengine-api-client-with-nodejs/","previous":{"fields":{"slug":"/should-use-delete-option-to-delete-git-branch-or-tag/"},"frontmatter":{"title":"リモートのタグを一括削除するときは–deleteを使おうと思った話","tags":["Git"]}},"next":{"fields":{"slug":"/automate-deploy-to-npm-with-circleci/"},"frontmatter":{"title":"npmへのデプロイをCircleCIで自動化してみた","tags":["CircleCI","Nodejs","npm"]}}}},
    "staticQueryHashes": ["2585454260","2954598359"]}