kintoneからMFクラウド請求書APIのPATCHメソッドを実行する

kintone から MF クラウド請求書 API の PATCH メソッドを実行する


にほんブログ村 IT技術ブログへ

はじめに

kintone から外部 API を仕様する際は、kintone.proxy() で実行します。
これは JavaScript で外部 API を実行するのに超えなきゃいけない CORS の壁に対する救済措置として存在しています。

このkintone.proxy()で実行できるHTTPメソッドは「GET,POST,PUT,DELETE」の4つです。
しかし、MFクラウド請求書APIでデータの変更をする場合は、PATCH でやらないといけないという事実を最近知りました。。。

MFクラウド請求書 API ドキュメント

moneyforward invoice api

PATCH メソッドとは?

恥ずかしながら初めて見ました。。。。

kintone の REST API も変更は PUT メソッドだったので、MFクラウド請求書APIも PUT だろうと勝手に思い込んでましたが。。。
実際作ろうと取り掛かった時に気づきました。。。

なんなんでしょうか?PATCH メソッドって?

MDN web doc より

HTTP PATCH リクエストメソッド はリソースへの部分的変更を適用します。

HTTP PUT メソッドは、ドキュメントの完全な置換のみを許可します。PUT とは違って、PATCH はべき等ではありません。すなわち、同一の PATCH リクエストが連続しておこなわれると、異なる効果が得られる可能性があります。ただし PATCH リクエストがべき等になるようにリクエストすることは可能です。

ほー。部分的変更の場合に使うんですね。
kintone の REST API は完全な置き換えだったんだ。
なるほど。

どうにかする

とにかく、どうにかしないといけない。
取引先マスタを変更したいのです。

それには CORS のやっかいな壁をどうにかしたい。
考えた結果、外部サーバにリクエストを代わりに実行してもらうしかないなと思い、
プロキシサーバを作ってみました。

リクエストの流れとしては、以下のようになります。

kintone ⇒ POST ⇒ プロキシサーバ ⇒ PATCH ⇒ MFクラウド請求書

これなら kintone.proxy() でも実行できますね。

プロキシサーバを Node.js で書いてみる

こんな感じです。

var express = require('express');
var request = require('request');
var app = express();

/** kintoneリクエストトークン */
var authToken = 'xxxxxx';
/** MFクラウド請求書 API URL */
var mfApiUrl = 'https://invoice.moneyforward.com/api/v2/partners';

/** 取引先変更用 オプション設定 */
var patchOptions = {
url: null,
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'Authorization': null
},
json: {}
}

/**
* express 初期設定
*/
app.set('port', (process.env.PORT || 5000));
app.use(express.json());

/**
* 簡易接続制限
*/
app.use(function (req, res, next) {
if (req.header('Authorization') === authToken && req.header('X-MF-App') !== undefined) {
next();
} else {
console.log('Authorization: ', req.header('Authorization'));
res.send({
status: 'Access Denied'
});
}
});

/**
* Top Page
*/
app.get('/', function (req, res) {
res.send('kintone App Space!!')
});

/**
* MFクラウド請求書
* 取引先 変更
*/
app.post('/api/mf/partners/change', (req, res) => {
// Authorizationヘッダにアクセストークン設定
patchOptions.headers.Authorization = req.header('X-MF-App');
patchOptions.url = mfApiUrl + '/' + req.query.id + '.json'
patchOptions.json = req.body;
// 取引先作成(PATCH)
request(patchOptions, function (error, response, body) {
res.send(body);
});
});

/**
* Webサーバ開始
*/
app.listen(app.get('port'), function () {
console.log("Node app is running at localhost:" + app.get('port'))
});

補足

  • POST で受け取ったデータを request オブジェクトで PATCH リクエスト実行。
  • PATCH リクエストのレスポンスをそのまま POST リクエストのレスポンスで返す。
  • Authorizationヘッダに REST API 認証トークンがセットされている想定。
  • 独自ヘッダ (X-MF-App) の方に MFクラウド請求書側のアクセストークンがセットされている想定。

kintone からプロキシサーバを利用した取引先マスタ変更

利用する kintone 側のコードは以下のような感じ。

/** MF請求書プロキシ URL */
const PROXY_URL = 'https://xxxxx.com/api/mf/partners/change?id=';

/** MFクラウド請求書側の取引先マスタ変更(プロキシ実行) */
const patchMfPartners = (partnerId, patchData, tokens) => {
return kintone.proxy(PROXY_URL + partnerId,
'POST',
{
'Authorization': tokens.proxyToken.value,
'Content-Type': 'application/json',
'X-MF-App': tokens.writeToken.value
},
patchData
).then((resp) => {
if (resp[1] === 200) {
var ret = JSON.parse(resp[0]);
return Promise.resolve(ret.data);
} else {
return Promise.reject(JSON.parse(resp[0]));
}
}).catch((err) => {
console.log('取引先変更エラー');
return Promise.reject(err);
});
}

補足

  • kintone.proxy() の使い方については こちら
  • callback 引数の省略して、kintone.Promise オブジェクト形式で実行。
  • プロキシサーバ側の認証情報をヘッダにセットするため、Authorization ヘッダを追加。
  • MFクラウド請求書APIを実行するための認証情報は「X-MF-App」という独自ヘッダにセット。

どうにか出来ました

  • kintone.proxy() が PATCH メソッドに対応していなかったため、自前でプロキシサーバを作って PATCH メソッドを実行できる環境を作ってみました。

  • kintone.proxy() 自体も今回書いたような事を裏でやっているのかなぁ、と思いました。

  • そういえば プロキシサーバ のアクセス制限をトークン的なものでやっていますが、本来ならアクセス元をちゃんと制限しておくべきでしたね。トークンだと基本的にどっからでもアクセス出来てしまいますね。そこは課題という事で。

wpmaster
  • wpmaster
  • フリーランスシステムエンジニアの鎌形です。
    鎌形システムエンジニアリングとして都内で活動中です。

%d人のブロガーが「いいね」をつけました。