SDK 설치하기
템플릿으로 만든 앱은 SDK가 이미 붙어 있어요. 바로 쓰는 법과, 직접 붙일 때의 설치 · 인증을 다뤄요.
SDK는 내 앱 코드에서 AxHub 기능(로그인한 사용자 · 회사 데이터)을 부르는 통로예요.
템플릿으로 만든 앱은 이미 붙어 있어서 설치할 게 없어요 — 바로 쓰기부터 보세요.
템플릿으로 만든 앱이라면
템플릿으로 만든 앱은 아래가 전부 준비된 상태로 시작해요.
| 준비된 것 | 내용 |
|---|---|
| SDK 설치 | @ax-hub/sdk가 이미 들어 있어요 (Next.js · Astro) |
| 접속 설정 | 배포할 때 API 주소 · 앱 슬러그 · 회사 슬러그가 코드에 채워져요 |
| 인증 | 토큰을 발급받지 않아요 — 앱에 들어온 사람의 로그인 정보를 그대로 써요 |
앱에 접속한 사람은 이미 회사 계정으로 로그인한 상태예요. 그 로그인 정보를 앱이 SDK에 그대로 넘기기 때문에, API 키를 따로 만들어 코드에 넣을 일이 없어요.
바로 쓰기
lib/axhub-server.ts의 makeAxhub()를 부르면 지금 요청을 보낸 사람의 자격으로 준비된 SDK가 나와요.
import { makeAxhub } from '@/lib/axhub-server';
const sdk = await makeAxhub();
const me = await sdk.identity.me();
// me.email, me.name, me.tenants (소속 회사와 역할)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.ts의 axhubFetch()가 로그인 정보를 실어 보내요.
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_URL | DB를 켠 앱 |
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()를 쓰세요 — 종류를 알아서 넣어 줘요 |
TenantSlugRequiredError | sdk.apps.*를 바로 부를 때 나요. makeTenant()를 거치면 회사 슬러그가 자동으로 붙어요 |
401 | 로그인이 풀렸거나 토큰이 잘못됐어요 |
이렇게 보이면 성공
sdk.identity.me()의 결과에 내 이메일과 소속 회사가 찍히면 준비가 끝난 거예요.
다음은 데이터베이스 연결하기에서 앱 전용 DB를 켜요.