Show HN: Instant API – JavaScript로 타입 안정성이 보장된 웹 API 구축하기
요약
Instant API는 JSDoc 주석을 활용하여 JavaScript 기반의 타입 안정성이 보장된 웹 API를 구축하는 프레임워크입니다. 스키마 검증 라이브러리 없이도 OpenAPI 명세를 자동 생성하며, 특히 LLM 스트리밍과 함수 호출(Function Calling) 통합에 최적화되어 있습니다.
핵심 포인트
- JSDoc을 통한 자동 스키마 검증 및 OpenAPI 명세 생성
- SSE(Server-Sent Events) 지원으로 LLM 응답 스트리밍 용이
- LLM 함수 호출을 위한 JSON 스키마 자동 출력 기능
- Autocode 엔진 기반의 높은 확장성과 안정성
Instant API
JavaScript로 타입 안정성이 보장된 웹 API를 즉시 구축하세요
스펙 생성 및 LLM 스트리밍
Instant API는 **HTTP 인터페이스에서 타입 안정성 (type-safety)**을 구현하는 JavaScript 기반 API 구축 프레임워크입니다. 이를 통해 스키마 검증 (schema validation) 라이브러리의 필요성을 완전히 제거합니다. API 엔드포인트를 나타내는 함수에 JSDoc 준수 주석 블록을 작성하기만 하면, 사용자 입력에 대한 검증 (validation), 정제 (sanitization) 및 테스트에 대해 더 이상 걱정할 필요가 없습니다. 그러면 API를 위한 OpenAPI 명세 (OpenAPI specification)가 localhost:8000/.well-known/openapi.json 및 localhost:8000/.well-known/openapi.yaml에 각각 JSON 및 YAML 형식으로 자동 생성됩니다.
또한, Instant API는 LLM 및 챗봇과의 통합에 최적화된 다음과 같은 여러 기능을 제공합니다:
text/event-stream을 사용하는 Server-Sent Events (SSE)에 대한 일급 지원으로 LLM 응답 스트리밍을 쉽게 구현할 수 있습니다.localhost:8000/.well-known/schema.json의 JSON 스키마 (JSON schema) 출력을 통해 LLM 함수 호출 (LLM function calling)을 쉽게 통합할 수 있습니다.localhost:8000/.well-known/ai-plugin.json의 실험적인 자동 생성 기능을 제공합니다.- Slack, Discord 웹훅 (webhook)을 위해 즉시
200 OK응답을 반환하고 백그라운드에서 실행할 수 있는 기능을 제공합니다.
Instant API는 초기 출시 버전임에도 불구하고 매우 다양한 기능을 갖춘 프레임워크임을 알 수 있을 것입니다. 이 프레임워크는 Autocode 서버리스 (serverless) 플랫폼의 엔진으로서 6년 동안 개발되어 왔으며, 하루 1억 건 이상의 API 요청을 처리할 수 있도록 수평적 확장 (horizontally scaled)을 이루었습니다.
빠른 예시: 표준 API
다음은 Instant API로 구축된 API 엔드포인트의 예시입니다. 이 엔드포인트는 HTTP GET을 통해 example.com/v1/weather/current URL에서 사용할 수 있습니다. location에는 길이 제한이 있고, coords.lat 및 coords.lng에는 범위 제한이 있으며, tags는 문자열 배열입니다. @returns 정의는 사용자와의 API 계약 (API contract)이 준수되도록 보장합니다. 만약 잘못된 데이터가 반환되면 에러가 발생합니다.
파일: /functions/v1/weather/current.mjs
/**
* 특정 위치의 날씨를 가져옵니다
* @param {?string{1..64}} location 위치로 검색
...
빠른 예시: LLM 스트리밍 (LLM Streaming)
LLM 스트리밍 (LLM streaming)은 간단합니다. 이는 특수한 context 객체에 의존하며, text/event-stream 응답을 생성하기 위해 @stream 파라미터를 정의합니다. @stream은 사용자에게 전달될 출력 스키마 (schema)를 지정한다는 점에서 @returns와 유사하다고 생각할 수 있습니다. 만약 이 계약 (contract)이 깨지면, API는 에러를 발생시킵니다. 사용자에게 스트림을 보내기 위해, 우리는 API 발자국 (footprint)의 마지막 파라미터로 특수한 context 객체를 추가하고 노출된 context.stream() 메서드를 사용합니다.
파일: /functions/v1/ai-helper.mjs
import OpenAI from 'openai';
const openai = new OpenAI(process.env.OPENAI_API_KEY);
...
기본적으로, 이 메서드는 다음과 같은 값을 반환합니다:
{
"content": "Hey there! 💁♀️ I'm doing great, thank you! 💖✨ How about you? 😊🌈"
}
하지만, 쿼리 파라미터 (query parameters)에 ?_stream을 추가하거나 바디 파라미터 (body parameters)에 {"_stream": true}를 추가하면, @begin과 @response 이벤트 사이에 context.stream() 이벤트가 끼워진 text/event-stream 형태로 변환됩니다. @response 이벤트는 API 호출이 정상적으로 이루어졌을 경우 HTTP 응답에 포함되었을 상세 내용을 담은 객체가 됩니다.
id: 2023-10-25T04:29:59.115000000Z/2e7c7860-4a66-4824-98fa-a7cf71946f19
event: @begin
data: "2023-10-25T04:29:59.115Z"
...
목차
목차
- 시작하기 (Getting Started)
- 엔드포인트 및 타입 안정성 (Endpoints and Type Safety)
- 엔드포인트 생성 (Creating Endpoints)
- HTTP 메서드에 응답하기 (Responding to HTTP methods)
- 타입 안정성 (Type Safety)
- 파라미터 검증 (Parameter validation)
- CORS (Cross-Origin Resource Sharing)
- 응답 반환 (Returning responses)
커스텀 HTTP 응답 (Custom HTTP responses)
- 버퍼 응답으로 파일 반환하기 (Returning files with Buffer responses)
- 스트리밍 응답 (Streaming responses)
- 디버그 응답 (Debug responses)
에러 발생시키기 (Throwing errors)
OpenAPI Specification 생성 (OpenAPI Specification Generation)
- OpenAPI 출력 예시 (OpenAPI Output Example)
- JSON Schema 출력 예시 (JSON Schema Output Example)
@private로 엔드포인트 숨기기
스트리밍 및 LLM 지원 (Streaming and LLM Support)
@stream타입 안정성context.stream()사용하기`_stream매개변수 사용하기- 특정 스트림만 선택적으로 듣기 (Selectively listening to specific streams)
웹훅 및 챗봇을 위한 백그라운드 실행 (Background execution for webhooks and chatbots)
디버깅 (Debugging)
내장 에러 (Built-in Errors)
테스트 (Testing)
- 테스트를 위한 퀵스타트 (Quickstart for tests)
- 테스트를 위한 커스텀 설치 (Custom installation for tests)
- 테스트 작성하기 (Writing tests)
- 테스트 실행하기 (Running tests)
배포 (Deployment)
instant deploy를 통한 배포 (#via-instant-deploy)- 커스텀 배포 (Custom deployments)
추가 정보 (More Information)
로드맵 및 피드백 (Roadmap and Feedback)
감사의 말 (Acknowledgements)
시작하기 (Getting Started)
퀵스타트 (Quickstart)
Instant API를 시작하는 가장 빠른 방법은 instant.dev command line tools를 사용하는 것입니다. 이는 Instant API 프로젝트를 설정하고, 새로운 엔드포인트 (endpoints)를 생성하며, 테스트를 관리하고, Vercel 또는 AWS를 위한 내장 배포 도구 (deployment tooling)를 사용하는 가장 쉬운 방법입니다. 또한 Instant ORM이 함께 패키징되어 있어 Postgres 기반의 백엔드 (backend)를 설정하는 것이 매우 간편합니다.
npm i instant.dev -g
cd ~/projects
mkdir my-new-project
...
그다음부터는 다음과 같은 더 고급 기능들을 사용할 수 있습니다:
# 엔드포인트 생성 (테스트가 자동으로 생성됨)
instant g:endpoint first_endpoint
...
사용자 정의 설치 (Custom installation)
참고: 이 문서의 대부분은 귀하가 instant.dev command line tool을 사용하고 있다고 가정합니다. 이는 Instant API 프로젝트를 설정하고, 새로운 엔드포인트를 생성하며, 테스트를 관리하고, Vercel 또는 AWS를 위한 내장 배포 도구를 사용하는 권장되는 방법입니다.
커맨드 라인 도구 없이 Instant API를 사용하려면 다음과 같이 할 수 있습니다:
cd path/to/my/project
npm i @instant.dev/api --save
그런 다음 package.json에 다음을 추가합니다:
"scripts": {
"start": "node instant.mjs"
},
그리고 다음 파일을 instant.mjs로 복사합니다:
// Third-party imports
import InstantAPI from '@instant.dev/api';
...
서버를 시작하려면 간단히 다음을 실행하세요:
npm start
엔드포인트 및 타입 안정성 (Endpoints and Type Safety)
Instant API는 엔드포인트 실행을 위해 Function as a Service (FaaS) 모델에 의존합니다. 즉, 모든 {Route, HTTP Method} 조합이 내보내기(exported) 함수로 모델링됩니다. 엔드포인트에 매개변수 검증(parameter validation), 즉 타입 안정성 (type safety)을 추가하려면, 약간 수정된 JSDoc 명세 주석 블록으로 내보낸 함수를 문서화하기만 하면 됩니다. 예를 들어, 가능한 가장 단순한 엔드포인트는 다음과 같습니다.
파일: functions/index.js
export default async function () {
return `hello world`;
}
다음과 같이 실행할 수 있습니다:
curl localhost:8000/
> "hello world"
instant serve 또는 npm start를 8000 포트에서 실행 중이라고 가정합니다. 서버 시작에 대한 자세한 내용은 Getting started를 참조하세요.
엔드포인트 (Endpoints) 생성하기
Instant API를 위한 엔드포인트를 생성하는 가장 쉬운 방법은 instant.dev 커맨드 라인 도구 (command line tools)를 사용하는 것입니다. 프로젝트가 초기화되면 다음과 같이 작성할 수 있습니다:
instant g:endpoint path/to/endpoint
짠! /functions/path/to/endpoint/index.mjs 위치에 새로운 빈 엔드포인트가 생성되었습니다.
수동으로 엔드포인트를 생성하고 싶다면, functions/ 디렉토리에 새로운 .mjs 파일을 생성하고, 해당 파일이 최소 하나 이상의 HTTP 메서드(GET, POST, PUT 또는 DELETE)에 대응하는 함수를 출력하도록 하면 됩니다.
HTTP 메서드에 응답하기
위의 예시에서는 export default를 사용하여 기본 함수를 내보냈습니다. 이 함수는 모든 GET, POST, PUT, DELETE 요청에 대해 동일한 함수로 응답합니다. 또는 다음과 같이 각 메서드별로 함수를 개별적으로 내보낼 수도 있습니다:
파일: functions/index.js
export async function GET () {
return `this was a GET request!`;
}
...
이러한 방식으로 지정되지 않은 모든 메서드는 자동으로 HTTP 501 에러 (Not Implemented)를 반환합니다. 엔드포인트를 다음과 같이 테스트할 수 있습니다:
curl -X GET localhost:8000/
> "this was a GET request!"
...
참고: 메서드 이름은 대소문자를 구분하며, 반드시 대문자여야 합니다. 내보내기(exports)가 제대로 읽히지 않으면 Instant API는 에러를 발생시킵니다.
엔드포인트 생명주기 (Endpoint lifecycle)
위의 functions/index.js와 같은 엔드포인트 파일에 접근할 때, 해당 파일은 프로세스당 단 한 번만 임포트(import)됩니다. export 문 외부의 코드는 함수가 처음 실행될 때 지연 실행(lazily executed)됩니다. 기본적으로 프로덕션 서버 환경에서 Instant API는 가상 코어(virtual core)당 하나의 프로세스를 시작합니다.
내보내기(export)된 각 함수는 호출될 때마다 실행됩니다. 대부분의 경우, 중요한 라이브러리 임포트(import)나 빈번하게 액세스되는 객체 캐싱(caching)을 위해서는 export 문 외부 영역을 사용해야 하며, 데이터 지속성(data persistence)을 위해서는 사용해서는 안 됩니다.
Instant ORM을 사용한 예시는 다음과 같습니다:
// 이렇게 하세요: 연결(connections) 및 자주 사용되는 객체, 생성자(constructors)를 캐싱합니다.
// 프로세스당 단 한 번만 실행됩니다: 첫 실행 시 지연 실행(lazily)됩니다.
...
다음은 하지 말아야 할 행동의 예시입니다:
// 이렇게 하지 마세요: 프로덕션 워크로드(production workloads)에서 데이터 지속성(data persistence)을 보장할 수 없습니다.
// 멀티 코어(multi-core) 서버이거나 Vercel과 같은 서버리스(serverless) 배포 환경일 수 있습니다.
...
엔드포인트(endpoint) 타이핑하기
AI 자동 생성 콘텐츠
본 콘텐츠는 HN Show HN (AI)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기