Node.js (GraphQL Request)
ステップ1. はじめに
ステップ1.1. 概要
Step 1の初期設定が完了すると、以下のようなAPIを簡単に利用することができます。
main.js
import { gql } from "graphql-request";
import { DeliveryTrackerGraphQLClient } from "./DeliveryTrackerGraphQLClient.js";
// DeliveryTracker Server と接続する Client を作成します。
const client = new DeliveryTrackerGraphQLClient(
"[YOUR_CLIENT_ID]",
"[YOUR_CLIENT_SECRET]"
);
// 最近のEventのtime, codeを取得するクエリの例
// 他にも様々なクエリが存在し、これにより様々な情報を照会することができます。
//
const trackQuery = gql`
query GetTrackLastEvent($carrierId: ID!、 $trackingNumber: String!) {
track(carrierId: $carrierId, trackingNumber: $trackingNumber) {
lastEvent {
time
status {
code
}
}
}
}
`;
// DeliveryTracker API を呼び出します。
const response = await client.request(trackQuery, {
carrierId: "kr.cjlogistics",
trackingNumber: "1234567890",
});
console.log(response);
ステップ1.2. 依存関係の追加
このドキュメントはgraphql-requestを使ってDelivery Tracker APIを使う方法を案内します。 このため、まずgraphql-requestをインストールします。
npm add graphql-request graphql
ステップ1.3. トランスポートクラスの追加
graphql-requestに内蔵された GraphQLClient
はDelivery Tracker Authを内蔵していません。
認証のため GraphQLClient
を継承し、Delivery Tracker Authが実装された DeliveryTrackerGraphQLClient
を追加します。
DeliveryTrackerGraphQLClient.js
import { GraphQLClient } from "graphql-request";
class DeliveryTrackerGraphQLClient extends GraphQLClient {
constructor(clientId, clientSecret) {
super("https://apis.tracker.delivery/graphql", {
fetch: (input, init) => this._fetch(input, init),
});
this._accessToken = null;
this._credentials = "Basic " + btoa(`${clientId}:${clientSecret}`);
}
async _fetch(input, init) {
let response = await fetch(input, {
...init,
headers: {
...init.headers,
"Authorization":`Bearer ${wait this.getAccessToken()}`,
}
});
let responseBody = await response.text();
if(this._hasUnauthenticatedError(JSON.parse(responseBody))){
response = await fetch(input, {
...init,
headers: {
...init.headers,
"Authorization":`Bearer ${await this.getAccessToken(true)}`,
}
});
responseBody = await response.text();
}
return {
ok: response.ok,
status: response.status,
headers: response.headers,
text: async () => responseBody,
};
}
_hasUnauthenticatedError(responseBody) {
if (!Array.isArray(responseBody.errors)) {
return false;
}
for (const error of responseBody.errors) {
try {
if (error.extensions?.code === "UNAUTHENTICATED") {
return true;
}
} catch (e) {}
}
return false;
}
async getAccessToken(forceFetchNewAccessToken = false) {
if (this._accessToken === null || forceFetchNewAccessToken) {
this._accessToken = await this._fetchNewAccessToken();
}
return this._accessToken;
}
async _fetchNewAccessToken() {
const authResponse = await fetch(
"https://auth.tracker.delivery/oauth2/token",
{
method: "POST",
headers: {
"Authorization":this._credentials,
"Content-Type":"application/x-www-form-urlencoded",
},
body: "grant_type=client_credentials",
},
);
if(authResponse.status >= 400) {
throw new Error(`Auth error: http response code=${authResponse.status} body=${await authResponse.text()}`);
}
try {
const authResponseBody = await authResponse.json();
const accessToken = authResponseBody.access_token;
if (typeof accessToken !== "string") {
throw new Error('typeof accessToken !== "string"');
}
return accessToken;
} catch (e) {
throw new Error("The access_token field was not found.", { cause: e });
}
}
}
export { DeliveryTrackerGraphQLClient };