K

SDK 설치하기

템플릿으로 만든 앱은 SDK가 이미 붙어 있어요. 바로 쓰는 법과, 직접 붙일 때의 설치 · 인증을 다뤄요.

SDK는 내 앱 코드에서 AxHub 기능(로그인한 사용자 · 회사 데이터)을 부르는 통로예요.
템플릿으로 만든 앱은 이미 붙어 있어서 설치할 게 없어요 — 바로 쓰기부터 보세요.

템플릿으로 만든 앱이라면

템플릿으로 만든 앱은 아래가 전부 준비된 상태로 시작해요.

준비된 것내용
SDK 설치@ax-hub/sdk가 이미 들어 있어요 (Next.js · Astro)
접속 설정배포할 때 API 주소 · 앱 슬러그 · 회사 슬러그가 코드에 채워져요
인증토큰을 발급받지 않아요 — 앱에 들어온 사람의 로그인 정보를 그대로 써요

앱에 접속한 사람은 이미 회사 계정으로 로그인한 상태예요. 그 로그인 정보를 앱이 SDK에 그대로 넘기기 때문에, API 키를 따로 만들어 코드에 넣을 일이 없어요.

바로 쓰기

lib/axhub-server.tsmakeAxhub()를 부르면 지금 요청을 보낸 사람의 자격으로 준비된 SDK가 나와요.

Next.js — 서버 컴포넌트 · 라우트 핸들러
import { makeAxhub } from '@/lib/axhub-server';

const sdk = await makeAxhub();
const me = await sdk.identity.me();
// me.email, me.name, me.tenants (소속 회사와 역할)
Astro
import { makeAxhub } from '../lib/axhub-server';

const sdk = makeAxhub({ cookie: Astro.request.headers.get('cookie') });
const me = await sdk.identity.me();

요청마다 makeAxhub()를 새로 부르세요. 만들어 둔 걸 모듈 바깥에 저장해 두고 재사용하면 어떤 사용자의 자격으로 부른 건지 섞여요.

화면만 있는 앱(Vite + React)이라면

이 템플릿은 브라우저에서만 돌아서 SDK를 쓰지 않아요. 대신 lib/axhub.tsaxhubFetch()가 로그인 정보를 실어 보내요.

import { axhubFetch } from './lib/axhub';

const res = await axhubFetch('/api/v1/me');
const me = await res.json();

로그인이 풀렸으면(401) 자동으로 AxHub 로그인으로 보냈다가 앱으로 돌려보내요.

템플릿 없이 만든 앱이라면

템플릿을 안 썼어도 토큰을 발급받을 필요는 없어요. 로그인 정보는 앱 주소로 같이 넘어와서, 그걸 꺼내 SDK에 넘기면 돼요. 템플릿이 하는 일도 이게 전부예요.

import { AxHubClient } from '@ax-hub/sdk';

// 요청마다 새로 만들어요.
const token = req.cookies['_hub_access'] ?? '';
const sdk = new AxHubClient({
  baseUrl: process.env.AXHUB_API_URL,
  ...(token ? { token, tokenType: 'jwt' as const } : {}),
  defaultTenantSlug: '<회사 슬러그>',
});

배포된 앱에는 아래 값들이 환경변수로 이미 들어와 있어요. 직접 넣지 않아도 돼요.

환경변수언제 들어오나요
AXHUB_API_URL모든 앱 — AxHub API 주소
AXHUB_APP_TOKEN모든 앱 — 알림 · 메일 발송 전용 열쇠
DATABASE_URL · DIRECT_DATABASE_URLDB를 켠 앱
STORAGE_ENDPOINT · STORAGE_BUCKET · STORAGE_ACCESS_KEY · STORAGE_SECRET_KEY스토리지를 켠 앱

AXHUB_APP_TOKEN알림 · 메일 발송에만 쓰는 토큰이에요. SDK 클라이언트에 넣으면 동작하지 않아요.

앱 밖에서 부르는 경우

CI 스크립트나 배치 작업처럼 로그인한 사람이 없는 곳에서는 넘겨받을 로그인 정보가 없어요. 이때만 토큰을 따로 발급받아요.

설치

npm install @ax-hub/sdk

여섯 SDK는 이름과 문법만 언어에 맞췄을 뿐, 같은 백엔드를 같은 방식으로 호출해요.

토큰 발급

PAT(개인 API 키)를 내 계정으로 로그인한 상태에서 발급해요.

curl -X POST "$AXHUB_API_URL/api/v1/me/personal-access-tokens" \
  -H "Authorization: Bearer <내 로그인 토큰>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "ci-script", "expires_in_days": 90 }'

발급 응답에 딱 한 번만 보여요. 그 자리에서 복사해 두지 않으면 다시 볼 수 없고, 새로 발급받아야 해요. expires_in_days를 빼면 만료 없이 계속 살아 있어요.

발급한 PAT는 내 계정 권한으로 동작해요 — 내가 못 하는 일은 이 키로도 못 해요. 목록 조회와 폐기는 SDK API — data에 있어요.

인증

발급받은 토큰으로 클라이언트를 만들어요.

import { AxHubClient } from '@ax-hub/sdk';

const sdk = new AxHubClient({
  token: process.env.AXHUB_TOKEN!,
  tokenType: 'pat',   // 'pat' | 'jwt'
});
  • 토큰 종류(tokenType)는 반드시 명시해요 — SDK가 추측하지 않아요.
  • 헤더 실어 보내는 건 SDK가 알아서 해요 — PAT는 X-Api-Key, JWT는 Authorization: Bearer로 나가요.
  • 토큰 값은 코드에 적지 말고 환경변수로 두세요 — 넣는 법은 환경변수 설정하기에 있어요.

PAT는 서버에서만 써요. 브라우저에서 도는 화면 코드에 넣으면 접속한 누구나 내 계정 권한을 가져가요.

오류가 났을 때

SDK는 e.code로 무슨 오류인지 알려줘요. 메시지 글자를 비교하지 말고 code로 분기하세요 — 메시지 문구는 나중에 바뀔 수 있어요.

import { AxHubError, ConflictError } from '@ax-hub/sdk';

try {
  await sdk.identity.me();
} catch (e) {
  if (e instanceof ConflictError) {
    // 이미 처리된 상태(중복) 처리
  } else if (e instanceof AxHubError) {
    console.error(e.code, e.requestId);
  }
}

자주 만나는 것들이에요.

상황어떻게 하나요
AxHubClient requires tokenType직접 new AxHubClient({ token })을 만들 때 나요. 템플릿 앱이라면 makeAxhub()를 쓰세요 — 종류를 알아서 넣어 줘요
TenantSlugRequiredErrorsdk.apps.*를 바로 부를 때 나요. makeTenant()를 거치면 회사 슬러그가 자동으로 붙어요
401로그인이 풀렸거나 토큰이 잘못됐어요

이렇게 보이면 성공

sdk.identity.me()의 결과에 내 이메일과 소속 회사가 찍히면 준비가 끝난 거예요.

다음은 데이터베이스 연결하기에서 앱 전용 DB를 켜요.