애플리케이션 만들기

애플리케이션 루프

배포 타깃에 맞춰 네이티브, Python, Web, HTTP 경로 중 하나를 선택해 진행합니다.

첫 애플리케이션 단계를 완료한 후 이 문서를 참조하세요. 코드 작성 절차는 배포 타깃과 관계없이 동일하지만, 배포 절차는 타깃마다 다릅니다. 모든 타깃을 순차적으로 빌드하지 마세요. 필요한 제품 하나만 선택하세요.

  • 언어 런타임 없이 특정 플랫폼에서 실행할 단일 파일이 필요하면 네이티브를 선택하세요.
  • 배포 환경에 Python 3.11 이상이 이미 설치되어 있다면 Python을 선택하세요.
  • 브라우저의 모델·메시지·상태 갱신 및 화면 제어를 토파즈가 소유한다면 Web 애플리케이션을 선택하세요.
  • 검사된 요청 핸들러를 프로세스 관리자 아래에서 실행하려면 HTTP 서비스를 선택하세요. 공개 서비스 형태라면 리버스 프록시 뒤에 둡니다.

Raw Web과 Worker 패키지는 기존 JavaScript 호스트에 연결하는 제품입니다. 자세한 내용은 WASM과 플레이그라운드에서 설명합니다.

공통 작성 과정

두 개의 모듈로 구성된 검사된 패키지에서 시작합니다. 예시로 사용하는 네이티브 패키지 매니페스트의 식별자는 다음과 같으며, 파일 이름은 topaz.toml입니다.

TOML
[package]
name = "task_summary"
version = "0.1.0"
language = "5.19"
entry = "src/main.tpz"

[build]
target = "native"
deterministic = true

[dependencies]
std = "5.19"

보조 모듈은 애플리케이션의 연산 로직을 담당합니다.

TOPAZ
export function 남은분(값들: Array<int>) -> int {
  let mut 합계 = 0
  for in 값들 {
    합계 +=
  }
  합계
}

진입 모듈은 연산 결과를 시각적으로 출력할 수 있는 명령으로 변환합니다.

TOPAZ
import src.summary { 남은분 }

export function main(인자: Array<string>, 표준입력: string) -> Result<int, string> {
  let = 남은분([10, 25])
  print("remaining={}")
  Ok(0)
}

topaz.lock 파일은 최초 1회 생성합니다. 일반적인 작업 순서도 아래와 같이 진행합니다.

BASH
topaz lock --root task-summary
topaz fmt --check --root task-summary
topaz check --root task-summary --locked
topaz test --root task-summary --locked
topaz run --root task-summary --locked

fmt --check는 파일을 수정하지 않고 코드 서식 차이만 알립니다. checktest 수행 중 오류가 발생하면 프로덕션 단계로 진행하기 전에 처리를 중단합니다. 출력된 토파즈 진단 중 첫 번째 항목을 수정한 후 동일한 명령을 다시 실행하세요. 진단 코드에 대한 상세 설명은 topaz explain TPZ####로 볼 수 있습니다.

경로 A: 네이티브 또는 Python 명령형 애플리케이션

네이티브 빌드를 수행하려면 현재 운영체제와 아키텍처를 지원하는 Rust 툴체인이 필요합니다. Python 빌드에는 Rust가 필요하지 않습니다. 대신 빌드된 제품을 실행하려면 Python 3.11 이상이 설치되어 있어야 합니다.

배포할 제품만 선택해 빌드합니다.

BASH
topaz build --release --root task-summary --locked --out-dir native-product
topaz build --target python --root task-summary --locked --out-dir python-product

릴리스 산출물의 구조는 다음과 같습니다.

출력
native-product/
├── GENERATED-OUTPUT-NOTICE.txt
├── LICENSE
├── NOTICE
├── target
│   └── release
│       └── program[.exe]
└── topaz-artifact.json

python-product/
├── GENERATED-OUTPUT-NOTICE.txt
├── LICENSE
├── NOTICE
├── program.py
├── topaz-artifact.json
└── topaz_py_rt.py

program[.exe] 표기는 Unix의 program과 Windows의 program.exe를 함께 나타냅니다. 선택한 디렉터리 전체를 새 위치로 복사하고 해당 루트 경로에서 실행하세요.

BASH
./target/release/program
python3 program.py

첫 번째 명령은 네이티브 제품에, 두 번째 명령은 Python 제품에 사용합니다. 둘 중 하나만 선택해 실행하세요. 애플리케이션이 [capabilities.fs]를 선언했다면 제품 옆에 data/ 디렉터리와 쓰기 가능한 출력 디렉터리를 생성하세요. 실행할 때는 해당 위치를 작업 디렉터리로 유지합니다. 애플리케이션 데이터는 네이티브나 Python 제품에 자동으로 포함되지 않습니다.

Rust 툴체인이 없다는 빌드 오류가 발생하면 호환되는 Rust 툴체인을 설치하세요. 그렇지 않다면 Python을 선택하세요. 출력 디렉터리에 다른 타깃이나 변경된 관리 파일이 존재한다면 원인 조사를 위해 해당 디렉터리는 그대로 둡니다. 빌드는 비어 있는 새 디렉터리에서 진행하세요.

경로 B: 관리형 Web 애플리케이션

Web 애플리케이션 빌드에는 wasm32-unknown-unknown 타깃이 설치된 Rust 툴체인이 필요합니다. 기존 명령형 진입점을 변환하지 말고 검사된 스캐폴드를 생성하세요.

BASH
topaz init --target web-app --root hello-web
topaz lock --root hello-web
topaz fmt --check --root hello-web
topaz check --root hello-web --locked
topaz test hello-web/tests/app.tpz --root hello-web --locked
topaz dev --root hello-web --port 8000
topaz build --root hello-web --locked --release --out-dir web-product

생성된 진입점은 검사 대상 생명주기를 사용합니다.

TOPAZ
import std.dom { Html, WebAppEvent, WebAppStep, text }

export record 모델 {
  메시지: string,
}

export enum 메시지종류 {
  준비,
}

export function init() -> WebAppStep<모델, 메시지종류> {
  WebAppStep { model: 모델 { 메시지: "Hello from Topaz" }, commands: [] }
}

export function update(모델값: 모델, 메시지: 메시지종류, 이벤트: WebAppEvent) -> WebAppStep<모델, 메시지종류> {
  WebAppStep { model: 모델값, commands: [] }
}

export function view(모델값: 모델) -> Html<메시지종류> {
  text(모델값.메시지)
}

topaz dev는 루프백에서 동작하는 개발용 서버입니다. 소스 코드를 잘못 수정하더라도 이전에 정상 빌드된 제품을 계속 제공하지만, 프로덕션 환경용 서버는 아닙니다. 최종 출력 디렉터리에는 HTML, 검사된 애플리케이션 호스트, Raw Web 연결 계층, WASM, 권한 메타데이터, 선언한 스타일·자산과 공통 라이선스·아티팩트 파일이 들어갑니다. 디렉터리 전체를 정적 호스트로 복사해 HTTP로 제공하세요. ES 모듈을 file:// 스킴으로 직접 구동하는 방식은 올바른 배포 경로가 아닙니다.

Data Lens는 이 경로를 사용하는 다중 모듈 예제이며 지속적으로 유지 관리합니다.

경로 C: HTTP 서비스

배포할 제품이 커맨드라인 명령이나 브라우저 UI가 아니라 요청 핸들러라면 서비스 스캐폴드를 생성하세요.

BASH
topaz init --target http-service --root hello-service
topaz lock --root hello-service
topaz fmt --check --root hello-service
topaz check --root hello-service --locked
topaz test --root hello-service --locked
topaz dev --root hello-service --port 8080
topaz build --root hello-service --locked --release --out-dir service-product

핸들러 경계는 명확하며 동기 방식으로 동작합니다.

TOPAZ
import std.http { HttpRequest, HttpResponse, text }

export function handle(요청: HttpRequest) -> HttpResponse {
  if 요청.url.path() == "/health" {
    return text(200, "ok")
  }
  text(404, "not found")
}

서비스 제품 패키지에는 단일 네이티브 실행 파일, 내장된 제한된 기본값, 제3자 고지와 공통 아티팩트 파일이 들어갑니다. 기본 바인드 주소는 루프백입니다. 루프백이 아닌 주소는 명시적인 프로세스 인수로 지정해야 합니다. TLS, HTTP/2, 아웃바운드 네트워크와 범용 Web 프레임워크는 추가되지 않습니다.

HTTP 서비스 문서에서 이 경로를 끝까지 다룹니다. 예산, 관찰 가능한 실패, 소스 없는 실행과 배포 복구 항목을 이어서 확인하세요.

관련 문서