본문으로 건너뛰기

Node.js (GraphQL Request)

Step 1. Getting started

Step 1.1. Overview

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 를 가져오는 예시 쿼리
// 그외 다양한 쿼리가 존재하며, 이를 통해 다양한 정보를 조회할 수 있습니다.
// 공식 사이트의 문서 및 API 스키마를 참고 해주세요.
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);

Step 1.2. Add dependencies

본 문서는 graphql-request을 사용하여 Delivery Tracker API를 사용하는 방법을 안내 합니다. 이를 위해 우선 graphql-request을 설치 합니다.

npm add graphql-request graphql

Step 1.3. Add Transport class

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 ${await 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 };

Step 1.4. Execute your first query

"Step 1.1. Overview"에 기재되어 있는 main.js 코드를 작성하고 main.js를 실행하면 API를 동작 시켜보세요.