1. 개요

이 기사에서는 RESTful API 를 설명하기 위해 YAML 1.2 및 JSON을 기반으로 구축 된 벤더 중립적 인 개방형 사양 언어 인 RESTful API 모델링 언어 (RAML)를 소개합니다 .

간단한 JSON 기반 API를 정의하는 방법을 보여 주면서 기본적인 RAML 1.0 구문과 파일 구조를 다룰 것입니다. 우리는 또한의 사용을 통해 RAML 파일 유지 관리를 단순화하는 방법을 보여 드리겠습니다 포함되어 있습니다 . JSON 스키마를 사용하는 레거시 API가있는 경우 스키마를 RAML에 통합하는 방법을 보여줍니다.

그런 다음 저작 도구, 문서 생성기 등을 포함하여 RAML 로의 여정을 향상시킬 수있는 몇 가지 도구를 소개합니다.

마지막으로 RAML 사양의 현재 상태를 설명하여 마무리하겠습니다.

2. API 정의 ( .raml 파일 생성 )

정의 할 API는 매우 간단합니다. 엔티티 유형 Foo가 주어지면 기본 CRUD 작업과 몇 가지 쿼리 작업을 정의합니다. API에 대해 정의 할 리소스는 다음과 같습니다.

  • GET / api / v1 / foos
  • POST / api / v1 / foos
  • GET / api / v1 / foos / {id}
  • PUT / api / v1 / foos / {id}
  • / api / v1 / foos / {id} 삭제
  • GET / api / v1 / foos / name / {name}
  • GET / api / v1 / foos? name = {name} & ownerName = {ownerName}

그리고 HTTP 기본 인증을 사용하여 상태를 저장하지 않고 HTTPS를 통해 암호화 된 상태로 전달되도록 API를 정의 해 보겠습니다. 마지막으로 데이터 전송 형식으로 JSON을 선택하겠습니다 (XML도 지원됨).

2.1. 루트 수준 설정

먼저 api.raml ( .raml 접두사 권장, 이름은 임의 임) 이라는 간단한 텍스트 파일을 만들고 첫 번째 줄에 RAML 버전 헤더를 추가합니다. 파일의 루트 수준에서 전체 API에 적용되는 설정을 정의합니다.

#%RAML 1.0
title: Baeldung Foo REST Services API using Data Types
version: v1
protocols: [ HTTPS ] 
baseUri: http://myapi.mysite.com/api/{version}
mediaType: application/json

3 행에서 " version " 이라는 단어 주위에 중괄호 {}를 사용합니다 . 이것이 RAML에 " 버전" 이 속성을 나타내며 확장 될 것이라고 말하는 방법 입니다. 따라서 실제 baseUrihttp://myapi.mysite.com/v1이됩니다.

[참고 : version 속성은 선택 사항이며 baseUri 의 일부일 필요는 없습니다 .]

2.2. Security

Security은 .raml 파일 의 루트 수준에서도 정의 됩니다. 이제 HTTP 기본 Security 체계 정의를 추가해 보겠습니다.

securitySchemes:
  basicAuth:
    description: Each request must contain the headers necessary for
                 basic authentication
    type: Basic Authentication
    describedBy:
      headers:
        Authorization:
          description: Used to send the Base64-encoded "username:password"
                       credentials
          type: string
      responses:
        401:
          description: |
            Unauthorized. Either the provided username and password
            combination is invalid, or the user is not allowed to access
            the content provided by the requested URL.

2.3. 데이터 유형

다음으로 API가 사용할 데이터 유형을 정의합니다.

types:
  Foo:
    type: object
    properties:
      id:
        required: true
        type: integer
      name:
        required: true
        type: string
      ownerName:
        required: false
        type: string

위의 예는 데이터 유형을 정의하기 위해 확장 구문을 사용합니다. RAML은 유형 정의를 덜 장황하게 만들기 위해 몇 가지 구문상의 단축키를 제공합니다. 다음은 이러한 단축키를 사용하는 동등한 데이터 유형 섹션입니다.

types:
  Foo:
    properties:
      id: integer
      name: string
      ownerName?: string
  Error:
    properties:
      code: integer
      message: string

'?' 속성 이름 뒤에 오는 문자는 속성이 필요하지 않음을 선언합니다.

2.4. 자원

이제 API의 최상위 리소스 (URI)를 정의합니다.

/foos:

2.5. URI 매개 변수

다음으로 리소스 List을 확장하여 최상위 리소스에서 빌드합니다.

/foos:
  /{id}:
  /name/{name}:

여기에서 속성 이름 주위의 중괄호 {}는 URI 매개 변수를 정의합니다. 이들은 각 URI의 자리 표시자를 나타내며 위의 baseUri 선언 에서 본 것처럼 루트 수준 RAML 파일 속성을 참조하지 않습니다 . 추가 된 줄은 리소스 / foos / {id}/ foos / name / {name}을 나타 냅니다.

2.6. 행동 양식

다음 단계는 각 리소스에 적용되는 HTTP 메서드를 정의하는 것입니다.

/foos:
  get:
  post:
  /{id}:
    get:
    put:
    delete:
  /name/{name}:
    get:

2.7. 쿼리 매개 변수

이제 쿼리 매개 변수를 사용하여 foos 컬렉션 을 쿼리하는 방법을 정의합니다 . 쿼리 매개 변수는 위에서 데이터 유형에 사용한 것과 동일한 구문을 사용하여 정의됩니다.

/foos:
  get:
    description: List all Foos matching query criteria, if provided;
                 otherwise list all Foos
    queryParameters:
      name?: string
      ownerName?: string

2.8. 응답

URI 매개 변수, HTTP 메소드, 쿼리 매개 변수를 포함하여 API에 대한 모든 리소스를 정의 했으므로 이제 예상 응답 및 상태 코드를 정의 할 차례입니다. 응답 형식은 일반적으로 데이터 유형 및 예와 관련하여 정의됩니다.

이전 버전의 RAML과의 역 호환성을 위해 데이터 유형 대신 JSON 스키마를 사용할 수 있습니다. 섹션 3에서 JSON 스키마를 소개합니다.

[참고 : 아래 코드 조각에서 세 개의 점 (…) 만 포함 된 줄은 간결성을 위해 일부 줄을 건너 뛰고 있음을 나타냅니다.]

/ foos / {id} 에 대한 간단한 GET 작업부터 시작하겠습니다 .

/foos:
  ...
  /{id}:
    get:
      description: Get a Foo by id
      responses:
        200:
          body:
            application/json:
              type: Foo
              example: { "id" : 1, "name" : "First Foo" }

이 예는 / foos / {id} 리소스에 대해 GET 요청을 수행 하여 JSON 객체 및 HTTP 상태 코드 200의 형식으로 일치하는 Foo반환해야 함을 보여줍니다 .

다음은 / foos 리소스 에 대한 GET 요청을 정의하는 방법입니다 .

/foos:
  get:
    description: List all Foos matching query criteria, if provided;
                 otherwise list all Foos
    queryParameters:
      name?: string
      ownerName?: string
    responses:
      200:
        body:
          application/json:
            type: Foo[]
            example: |
              [
                { "id" : 1, "name" : "First Foo" },
                { "id" : 2, "name" : "Second Foo" }
              ]

Foo 유형에 추가 된 대괄호 [] 사용에 유의하십시오 . 이것은 Foo 객체 의 배열을 포함하는 Response body을 정의하는 방법을 보여줍니다 . 예제는 JSON 객체의 배열입니다.

2.9. 요청 본문

다음으로 각 POST 및 PUT 요청에 해당하는 요청 본문을 정의합니다. 새로운 Foo 객체 를 생성하는 것부터 시작하겠습니다 .

/foos:
  ...
  post:
    description: Create a new Foo
    body:
      application/json:
        type: Foo
        example: { "id" : 5, "name" : "Another foo" }
    responses:
      201:
        body:
          application/json:
            type: Foo
            example: { "id" : 5, "name" : "Another foo" }

2.10. 상태 코드

위의 예에서 새 객체를 만들 때 HTTP 상태 201을 반환합니다. 객체 업데이트를위한 PUT 작업은 POST 작업과 동일한 요청 및 Response body을 사용하여 HTTP 상태 200을 반환합니다.

요청이 성공할 때 반환되는 예상 응답 및 상태 코드 외에도 오류 발생시 예상 할 응답의 종류와 상태 코드를 정의 할 수 있습니다.

주어진 ID를 가진 리소스를 찾을 수 없을 때 / foos / {id} 리소스 에 대한 GET 요청에 대한 예상 응답을 정의하는 방법을 살펴 보겠습니다 .

        404:
          body:
            application/json:
              type: Error
              example: { "message" : "Not found", "code" : 1001 }

3. JSON 스키마를 사용한 RAML

RAML 1.0에 데이터 유형 이 도입 되기 전에는 객체, 요청 본문 및 Response body이 JSON 스키마를 사용하여 정의되었습니다.

데이터 유형을 사용 하는 것은 매우 강력 할 수 있지만 여전히 JSON 스키마를 사용하려는 경우가 있습니다. RAML 0.8에서는 루트 수준 스키마 섹션을 사용하여 스키마를 정의했습니다 .

여전히 유효하지만 스키마 사용은 향후 버전에서 더 이상 사용되지 않을 수 있으므로 대신 types 섹션 을 사용하는 것이 좋습니다 . 유형스키마 뿐만 아니라 유형스키마 , 동의어입니다.

다음은 JSON 스키마를 사용하여 .raml 파일 의 루트 수준에서 Foo 객체 유형을 정의하는 방법입니다 .

types:
  foo: |
    { "$schema": "http://json-schema.org/schema",
       "type": "object",
       "description": "Foo details",
       "properties": {
         "id": { "type": integer },
         "name": { "type": "string" },
         "ownerName": { "type": "string" }
       },
       "required": [ "id", "name" ]
    }

다음은 GET / foos / {id} 리소스 정의 에서 스키마를 참조하는 방법입니다 .

/foos:
  ...
  /{id}:
    get:
      description: Get a Foo by its id
      responses:
        200:
          body:
            application/json:
              type: foo
              ...

4. Include로 리팩토링

위 섹션에서 볼 수 있듯이 API는 다소 장황하고 반복적입니다.

RAML 사양은 반복되고 긴 코드 섹션을 외부화 할 수있는 포함 메커니즘을 제공합니다.

포함을 사용하여 API 정의를 리팩토링하여 "모든 위치에 복사 / 붙여 넣기 / 수정"방법론에서 발생하는 오류 유형을 더 간결하게 만들고 포함 할 가능성을 줄일 수 있습니다.

예를 들어, Foo 객체에 대한 데이터 유형 은 파일 types / Foo.raml 에, Error 객체에 대한 유형types / Error.raml에 넣을 수 있습니다. 그러면 유형 섹션은 다음과 같습니다.

types:
  Foo: !include types/Foo.raml
  Error: !include types/Error.raml

대신 JSON 스키마를 사용하는 경우 유형 섹션은 다음과 같습니다.

types:
  foo: !include schemas/foo.json
  error: !include schemas/error.json

5. API 완성

모든 데이터 유형과 예제를 파일로 구체화 한 후 include 기능을 사용하여 API를 리팩터링 할 수 있습니다.

#%RAML 1.0
title: Baeldung Foo REST Services API
version: v1
protocols: [ HTTPS ]
baseUri: http://rest-api.baeldung.com/api/{version}
mediaType: application/json
securedBy: basicAuth
securitySchemes:
  basicAuth:
    description: Each request must contain the headers necessary for
                 basic authentication
    type: Basic Authentication
    describedBy:
      headers:
        Authorization:
          description: Used to send the Base64 encoded "username:password"
                       credentials
          type: string
      responses:
        401:
          description: |
            Unauthorized. Either the provided username and password
            combination is invalid, or the user is not allowed to access
            the content provided by the requested URL.
types:
  Foo:   !include types/Foo.raml
  Error: !include types/Error.raml
/foos:
  get:
    description: List all Foos matching query criteria, if provided;
                 otherwise list all Foos
    queryParameters:
      name?: string
      ownerName?: string
    responses:
      200:
        body:
          application/json:
            type: Foo[]
            example: !include examples/Foos.json
  post:
    description: Create a new Foo
    body:
      application/json:
        type: Foo
        example: !include examples/Foo.json
    responses:
      201:
        body:
          application/json:
            type: Foo
            example: !include examples/Foo.json
  /{id}:
    get:
      description: Get a Foo by id
      responses:
        200:
          body:
            application/json:
              type: Foo
              example: !include examples/Foo.json
        404:
          body:
            application/json:
              type: Error
              example: !include examples/Error.json
    put:
      description: Update a Foo by id
      body:
        application/json:
          type: Foo
          example: !include examples/Foo.json
      responses:
        200:
          body:
            application/json:
              type: Foo
              example: !include examples/Foo.json
        404:
          body:
            application/json:
              type: Error
              example: !include examples/Error.json
    delete:
      description: Delete a Foo by id
      responses:
        204:
        404:
          body:
            application/json:
              type: Error
              example: !include examples/Error.json
  /name/{name}:
    get:
      description: List all Foos with a certain name
      responses:
        200:
          body:
            application/json:
              type: Foo[]
              example: !include examples/Foos.json

6. RAML 도구

RAML의 가장 큰 장점 중 하나는 도구 지원입니다.

RAML API의 구문 분석, 유효성 검사 및 작성을위한 도구가 있습니다. 클라이언트 코드 생성을위한 도구; HTML 및 PDF 형식으로 API 문서를 생성하기위한 도구; RAML API 사양에 대한 테스트를 지원하는 도구.

Swagger JSON API를 RAML로 변환하는 도구도 있습니다.

다음은 사용 가능한 도구의 예입니다.

  • API Designer – 빠르고 효율적인 API 설계를위한 웹 기반 도구
  • API Workbench – RAML 0.8 및 1.0을 모두 지원하는 RESTful API를 설계, 빌드, 테스트 및 문서화하기위한 IDE
  • RAML Cop – RAML 파일 유효성 검사 도구
  • JAX-RS 용 RAML – RAML 사양에서 Java + JAX-RS 애플리케이션 코드의 골격을 생성하거나 기존 JAX-RS 애플리케이션에서 RAML 사양을 생성하기위한 도구 세트
  • RAML Sublime Plugin – Sublime 텍스트 편집 기용 구문 하이 라이터 플러그인
  • RAML to HTMLRAML에서 HTML 문서를 생성하는 도구
  • raml2pdfRAML 에서 PDF 문서를 생성하는 도구
  • RAML2Wiki – Wiki 문서 생성 도구 (Confluence / JIRA 마크 업 사용)
  • SoapUI RAML 플러그인 – 인기있는 SoapUI 기능 API 테스트 제품군을위한 RAML 플러그인
  • Vigia – RAML 정의를 기반으로 테스트 케이스를 생성 할 수있는 통합 테스트 스위트

RAML 도구 및 관련 프로젝트의 전체 List을 보려면 RAML 프로젝트 페이지를 방문 하십시오.

7. RAML의 현재 상태

RAML 1.0 (RC) 사양은 2015 년 11 월 3 일에 릴리스 후보 상태를 얻었으며이 문서를 작성하는 시점에 버전 1.0은 한 달 안에 완성 될 것으로 예상되었습니다.

이전 버전 인 RAML 0.8은 원래 2014 년 가을에 출시되었으며 여전히 무수한 도구에서 지원됩니다.

8. 더 읽을 거리

다음은 RAML과의 여정에서 유용 할 수있는 몇 가지 링크입니다.

9. 결론

이 기사에서는 RESTful API 모델링 언어 (RAML)를 소개했습니다. RAML 1.0 (RC) 사양을 사용하여 간단한 API 사양을 작성하기위한 몇 가지 기본 구문을 시연했습니다.

그리고 구문 단축키를 사용하고 예제, 데이터 유형 및 스키마를 '포함'파일로 구체화하여 정의를보다 간결하게 만드는 방법을 보았습니다.

그런 다음 일상적인 API 설계, 개발, 테스트 및 문서화 작업을 지원하기 위해 RAML 사양과 함께 작동하는 강력한 도구 모음을 도입했습니다.

도구 개발자의 압도적 인 지원과 함께 다가오는 사양 버전 1.0의 공식 릴리스를 통해 RAML이 계속 유지 될 것 같습니다.

다음 »
리소스 유형 및 특성을 사용하여 RAML의 중복 제거