Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

서비스 사용자로 실행하는 TypeScript 서버 앱

서버 앱은 사용자 대신 서비스 사용자(Service user)의 권한으로 OSDK를 호출할 수 있습니다. 기밀 OAuth client secret을 보관하므로 이 코드는 서버에서만 실행해야 합니다. 같은 서비스 사용자가 읽을 수 있는 데이터를 어느 앱 사용자에게 보여 줄지는 서버 앱의 별도 인증과 인가 정책으로 정해야 합니다.

다른 조직의 온톨로지를 사용하는 경우에는 조직 간 앱 공유와 활성화도 필요할 수 있습니다.

Developer Console 설정

  1. 앱 생성의 Application type에서 Backend service를 선택합니다.

  1. Permissions에서 Application's permissions를 선택합니다.

앱 이름을 기준으로 서비스 사용자가 만들어집니다. 선택할 객체의 데이터를 읽을 권한 및 실행할 액션의 제출 조건을 이 사용자에게 부여해야 합니다. 앱 생성이 데이터 권한을 자동으로 부여하지는 않습니다.

  1. Resources에서 Yes, generate an Ontology SDK를 선택합니다.

  1. 온톨로지와 필요한 객체 및 액션을 고릅니다. 첫 SDK 생성 뒤에는 연결 온톨로지를 바꿀 수 없습니다.

  1. Create application을 선택하고 한 번만 표시하는 client secret을 안전하게 저장합니다.

잃으면 OAuth & restrictions에서 회전하여 새 값을 만들어야 합니다. 이전 값을 사용하는 앱은 실패하므로 소비 서버를 함께 갱신해야 합니다. Marketplace는 secret을 포함하지 않으며 설치 대상에서 Rotate secret으로 새 값을 만듭니다.

  1. Generate first version을 선택하고 화면의 설치 절차로 생성 SDK를 서버 프로젝트에 설치합니다.

Next.js 서버 예제

다음은 App Router와 connection()을 지원하는 Next.js 서버 앱의 예입니다. 정적 Foundry 웹 호스팅에는 이 서버 코드를 실행할 수 없으므로 Node 서버를 실행하는 별도 호스팅 환경이 필요합니다.

서버 실행 환경에 CLIENT_ID, CLIENT_SECRET, STACK_URL과 ONTOLOGY_RID를 제공합니다. STACK_URL은 실제 HTTPS 플랫폼 URL입니다. 로컬 .env.local을 사용하는 경우 소스 제어에 포함하지 않으며 비밀값에 NEXT_PUBLIC_ 접두사를 붙이지 않습니다.

서버 전용 클라이언트

src/app/client.ts에 작성합니다. 서버 전용 모듈이므로 Client Component로 가져오면 빌드 오류가 발생합니다. 첫 서버 요청에서 생성하고 이후에는 같은 인증 클라이언트를 재사용합니다.

import "server-only";
import { createConfidentialOauthClient } from "@osdk/oauth";
import { Client, createClient } from "@osdk/client";

let serverClient: Client | undefined;

function requiredEnv(name: string): string {
    const value = process.env[name];
    if (value === undefined || value.length === 0) throw new Error(`서버 환경 변수 ${name}이 필요합니다.`);
    return value;
}

export function getServerClient(): Client {
    if (serverClient === undefined) {
        const url = requiredEnv("STACK_URL");
        const auth = createConfidentialOauthClient(
            requiredEnv("CLIENT_ID"), requiredEnv("CLIENT_SECRET"), url,
            ["api:use-ontologies-read"],
        );
        serverClient = createClient(url, requiredEnv("ONTOLOGY_RID"), auth);
    }
    return serverClient;
}

기밀 OAuth 제공자는 필요할 때 client credentials로 토큰을 받고 유효한 토큰을 재사용합니다. secret을 사용자 브라우저에 전달하거나 로그에 출력하지 않습니다.

첫 국가 페이지 조회

가상의 생성 패키지 @serverside-osdk-example/sdk에 Country와 countryName이 있다고 가정합니다. src/app/page.tsx에서 첫 페이지를 읽습니다. connection() 뒤에 런타임 클라이언트를 요청하므로 빌드 시점에 데이터를 정적으로 읽지 않습니다.

import { connection } from "next/server";
import { Country } from "@serverside-osdk-example/sdk";
import { getServerClient } from "./client";

export default async function Home() {
    await connection();
    const countries = await getServerClient()(Country).fetchPage({ $pageSize: 30 });
    return (
        <main>
            <h1>국가 목록의 첫 페이지</h1>
            {countries.data.length === 0 ? <p>조회 가능한 국가가 없습니다.</p> : (
                <ul>{countries.data.map(country => (
                    <li key={country.$primaryKey}>{country.countryName ?? country.$primaryKey}</li>
                ))}</ul>
            )}
        </main>
    );
}

실패는 Next.js의 오류 처리 경계로 전파합니다. 권한 또는 네트워크 오류를 국가가 없는 정상 결과로 바꾸지 않습니다. 이 예제는 별도 end-user 로그인 기능을 구현하지 않으므로 서비스 데이터가 허용된 사용자에게만 노출되도록 기존 앱의 인증 경계 안에 배치합니다.

npm run dev

기본 개발 주소는 http://localhost:3000입니다. 실제 실행은 서비스 사용자 권한으로 데이터를 조회합니다. 생성 SDK의 타입과 호출은 TypeScript OSDK 참조를 따릅니다.