본문으로 건너뛰기

API와 OpenAPI

이 페이지는 영어에서 번역되었습니다. 영어 페이지 읽기

모든 action은 JSON 엔드포인트가 될 수도 있습니다. 같은 입력 형식, 같은 규칙, 같은 권한이 적용되므로 API가 Screen과 어긋날 수 없습니다.

action 게시하기

Feature::new("stock")
    .api(search_products)
    .api(save_product)
    .api(restock_product)

각 action은 POST /api/v1/{feature}/{action}이 되며, 예를 들면 POST /api/v1/stock/save_product입니다. 본문은 JSON 형태의 action 입력이고 응답은 JSON 형태의 출력입니다.

curl -X POST http://127.0.0.1:3002/api/v1/stock/search_products \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"sort":[{"field":"code","desc":false}]}'

App::api_prefix("/api/v2")로 접두사를 바꿀 수 있습니다.

호출자를 위한 규칙

  • 호출에는 Authorization 헤더가 필요합니다. 앱의 인증기가 이를 읽으며, 브라우저 세션 쿠키만으로는 거부되므로 API에는 CSRF 토큰이 필요하지 않습니다.
  • 접근 권한, 가드, 인터셉터, 감사, 속도 제한은 Screen과 똑같이 적용됩니다.
  • Valid<M>을 받는 입력은 모든 #[rule]을 실행합니다. 필드 오류는 각 필드의 메시지와 함께 422로 돌아옵니다.
  • 목록은 DataQuery를 받아 Page를 반환하며, 서버가 페이지 크기에 상한을 둡니다.

오류

오류는 RFC 9457 problem details(application/problem+json)입니다.

{
  "type": "urn:zeyn:problem:validation",
  "title": "Unprocessable Entity",
  "status": 422,
  "detail": "Some fields are not valid.",
  "errors": [{ "field": "code", "rule": "unique", "message": "This code is already used." }]
}
상태type의 끝발생 시점
403forbiddenAuthorization 헤더가 없거나 권한이 없는 경우
404not_found알 수 없는 레코드이거나 파싱되지 않는 입력
409conflict행 버전이 바뀐 경우
422validation필드 오류
429forbidden요청이 너무 많음. Retry-After를 확인하십시오
504timeout호출이 서버 제한 시간보다 오래 걸린 경우

OpenAPI

App::new(t!("app.name")).api_docs(ApiDocs::open())

api_docs를 사용하면 앱이 {api_prefix}/openapi.json(OpenAPI 3.1이며 Postman, 클라이언트 생성기, 모든 OpenAPI 뷰어로 가져올 수 있습니다)과 {api_prefix}/docs의 읽기 쉬운 레퍼런스를 게시합니다. 스키마는 모델에서 만들어집니다. 형식, 필수 필드, 길이, 범위, choice 값이 포함됩니다.

문서에는 모든 엔드포인트와 필요한 권한이 나열되므로 기본적으로 꺼져 있습니다. 누가 읽을 수 있는지 선택합니다.

접근대상
ApiDocs::open()누구나
ApiDocs::basic(credentials)HTTP 기본 인증, 예를 들어 StaticCredentials::new("docs", password)
ApiDocs::permission("api.docs.read")해당 권한을 가진 로그인한 사용자

다른 출처의 브라우저 앱

App::cors(["https://app.example.com"])는 정확히 이 출처의 브라우저 앱이 Authorization 헤더와 함께 API를 호출하도록 허용합니다. 쿠키는 출처를 넘어 전송되지 않습니다.