REST 사양으로 해본 적이 없는 5가지
게시 됨: 2022-03-11대부분의 프론트엔드 및 백엔드 개발자는 이전에 REST 사양 및 RESTful API를 다루었습니다. 그러나 모든 RESTful API가 동일하게 생성되는 것은 아닙니다. 사실, 그들은 거의 RESTful하지 않습니다…
RESTful API란 무엇 입니까 ?
그것은 신화입니다.
프로젝트에 RESTful API가 있다고 생각한다면 착각일 가능성이 큽니다. RESTful API의 이면에 있는 아이디어는 REST 사양에 설명된 모든 아키텍처 규칙 및 제한 사항을 따르는 방식으로 개발하는 것입니다. 그러나 현실적으로 현실적으로 불가능한 경우가 많다.
한편으로 REST에는 너무 흐릿하고 모호한 정의가 포함되어 있습니다. 예를 들어, 실제로 HTTP 메소드 및 상태 코드 사전의 일부 용어는 의도한 목적과 다르게 사용되거나 전혀 사용되지 않습니다.
반면에 REST 개발은 너무 많은 제한 사항을 만듭니다. 예를 들어 원자 자원 사용은 모바일 애플리케이션에서 사용되는 실제 API에 대해 차선책입니다. 요청 간의 데이터 저장에 대한 전체 거부는 거의 모든 곳에서 볼 수 있는 "사용자 세션" 메커니즘을 기본적으로 금지합니다.
하지만 잠깐, 그렇게 나쁘지 않아!
REST API 사양은 무엇을 위해 필요합니까?
이러한 단점에도 불구하고 합리적인 접근 방식을 사용하더라도 REST는 여전히 훌륭한 API를 만들기 위한 놀라운 개념입니다. 이러한 API는 일관되고 명확한 구조, 우수한 문서 및 높은 단위 테스트 범위를 가질 수 있습니다. 고품질 API 사양 으로 이 모든 것을 달성할 수 있습니다.
일반적으로 REST API 사양은 해당 설명서 와 연결됩니다. API에 대한 형식적인 설명인 사양과 달리 문서는 사람이 읽을 수 있어야 합니다. 예를 들어 API를 사용하는 모바일 또는 웹 애플리케이션 개발자가 읽을 수 있습니다.
올바른 API 설명은 API 문서를 잘 작성하는 것만이 아닙니다. 이 기사에서는 다음을 수행할 수 있는 방법의 예를 공유하고자 합니다.
- 단위 테스트를 더 간단하고 안정적으로 만드십시오.
- 사용자 입력 전처리 및 유효성 검사를 설정합니다.
- 직렬화를 자동화하고 응답 일관성을 보장합니다. 그리고 심지어
- 정적 입력의 이점을 누리십시오.
하지만 먼저 API 사양 세계에 대한 소개부터 시작하겠습니다.
오픈API
OpenAPI는 현재 REST API 사양에 대해 가장 널리 허용되는 형식입니다. 사양은 다음 세 섹션으로 구성된 JSON 또는 YAML 형식의 단일 파일에 작성됩니다.
- API 이름, 설명, 버전 및 추가 정보가 포함된 헤더입니다.
- 식별자, HTTP 메서드, 모든 입력 매개변수, 응답 코드 및 본문 데이터 유형을 포함한 모든 리소스에 대한 설명과 정의에 대한 링크.
- JSON 스키마 형식으로 입력 또는 출력에 사용할 수 있는 모든 정의(예, YAML로도 표시할 수 있음)
OpenAPI의 구조에는 두 가지 중요한 단점이 있습니다. 너무 복잡하고 때로는 중복됩니다. 소규모 프로젝트는 수천 줄의 JSON 사양을 가질 수 있습니다. 이 파일을 수동으로 유지 관리하는 것은 불가능해집니다. 이것은 API가 개발되는 동안 사양을 최신 상태로 유지하려는 아이디어에 중대한 위협이 됩니다.
API를 설명하고 OpenAPI 출력을 생성할 수 있는 여러 편집기가 있습니다. 이를 기반으로 하는 추가 서비스 및 클라우드 솔루션에는 Swagger, Apiary, Stoplight, Restlet 등이 있습니다.
그러나 이러한 서비스는 빠른 사양 편집과 코드 변경에 따른 정렬이 복잡하기 때문에 불편했습니다. 또한 기능 목록은 특정 서비스에 종속되었습니다. 예를 들어 클라우드 서비스의 도구를 기반으로 본격적인 단위 테스트를 만드는 것은 거의 불가능합니다. 코드 생성과 끝점 조롱은 실용적인 것처럼 보이지만 실제로는 거의 쓸모가 없는 것으로 판명되었습니다. 이는 주로 엔드포인트 동작이 사용자 권한 및 입력 매개변수와 같은 다양한 항목에 따라 달라지기 때문입니다. 이는 API 설계자에게는 분명할 수 있지만 OpenAPI 사양에서 자동으로 생성하기 쉽지 않습니다.
타이니 스펙
이 기사에서는 나만의 REST API 정의 형식인 tinyspec 을 기반으로 하는 예제를 사용합니다. 정의는 직관적인 구문을 가진 작은 파일로 구성됩니다. 프로젝트에서 사용되는 끝점 및 데이터 모델을 설명합니다. 파일은 코드 옆에 저장되어 빠른 참조와 코드 작성 중에 편집할 수 있는 기능을 제공합니다. Tinyspec은 프로젝트에서 즉시 사용할 수 있는 본격적인 OpenAPI 형식으로 자동 컴파일됩니다.
Node.js(Koa, Express) 및 Ruby on Rails 예제도 사용하지만, 제가 시연할 사례는 Python, PHP, Java를 포함한 대부분의 기술에 적용할 수 있습니다.
API 사양이 흔들리는 곳
이제 약간의 배경 지식이 있으므로 적절하게 지정된 API를 최대한 활용하는 방법을 탐색할 수 있습니다.
1. 엔드포인트 단위 테스트
행동 주도 개발(BDD)은 REST API 개발에 이상적입니다. 별도의 클래스, 모델 또는 컨트롤러가 아닌 특정 끝점에 대한 단위 테스트를 작성하는 것이 가장 좋습니다. 각 테스트에서 실제 HTTP 요청을 에뮬레이트하고 서버의 응답을 확인합니다. Node.js의 경우 요청을 에뮬레이트하기 위한 supertest 및 chai-http 패키지가 있고 Ruby on Rails의 경우 airborne이 있습니다.
User
스키마와 모든 사용자를 반환하는 GET /users
엔드포인트가 있다고 가정해 보겠습니다. 다음은 이것을 설명하는 몇 가지 tinyspec 구문입니다.
# user.models.tinyspec User {name, isAdmin: b, age?: i} # users.endpoints.tinyspec GET /users => {users: User[]}
다음은 해당 테스트를 작성하는 방법입니다.
노드.js
describe('/users', () => { it('List all users', async () => { const { status, body: { users } } = request.get('/users'); expect(status).to.equal(200); expect(users[0].name).to.be('string'); expect(users[0].isAdmin).to.be('boolean'); expect(users[0].age).to.be.oneOf(['boolean', null]); }); });
루비 온 레일즈
describe 'GET /users' do it 'List all users' do get '/users' expect_status(200) expect_json_types('users.*', { name: :string, isAdmin: :boolean, age: :integer_or_null, }) end end
서버 응답을 설명하는 사양이 이미 있는 경우 테스트를 단순화하고 응답이 사양을 따르는지 확인할 수 있습니다. 우리는 각각 JSON 스키마 형식을 따르는 OpenAPI 사양으로 변환될 수 있는 tinyspec 모델을 사용할 수 있습니다.
JS의 모든 리터럴 객체(또는 Ruby의 Hash
, Python의 dict
, PHP의 연관 배열 , Java의 Map
)는 JSON 스키마 준수에 대해 유효성을 검사할 수 있습니다. 프레임워크 테스트를 위한 적절한 플러그인도 있습니다(예: jest-ajv(npm), chai-ajv-json-schema(npm), RSpec용 json_matcher(rubygem)).
스키마를 사용하기 전에 프로젝트로 가져오도록 하겠습니다. 먼저, tinyspec 사양을 기반으로 openapi.json
파일을 생성합니다(각 테스트 실행 전에 자동으로 이 작업을 수행할 수 있음).
tinyspec -j -o openapi.json
노드.js
이제 프로젝트에서 생성된 JSON을 사용하고 여기에서 definitions
키를 가져올 수 있습니다. 이 키는 모든 JSON 스키마를 포함합니다. 스키마에는 상호 참조( $ref
)가 포함될 수 있으므로 포함된 스키마(예 Blog {posts: Post[]}
)가 있는 경우 유효성 검사에 사용하기 위해 해당 스키마를 풀어야 합니다. 이를 위해 json-schema-deref-sync(npm)를 사용합니다.
import deref from 'json-schema-deref-sync'; const spec = require('./openapi.json'); const schemas = deref(spec).definitions; describe('/users', () => { it('List all users', async () => { const { status, body: { users } } = request.get('/users'); expect(status).to.equal(200); // Chai expect(users[0]).to.be.validWithSchema(schemas.User); // Jest expect(users[0]).toMatchSchema(schemas.User); }); });
루비 온 레일즈
json_matchers
모듈은 $ref
참조를 처리하는 방법을 알고 있지만 지정된 위치에 별도의 스키마 파일이 필요하므로 먼저 swagger.json
파일을 여러 개의 작은 파일로 분할해야 합니다.
# ./spec/support/json_schemas.rb require 'json' require 'json_matchers/rspec' JsonMatchers.schema_root = 'spec/schemas' # Fix for json_matchers single-file restriction file = File.read 'spec/schemas/openapi.json' swagger = JSON.parse(file, symbolize_names: true) swagger[:definitions].keys.each do |key| File.open("spec/schemas/#{key}.json", 'w') do |f| f.write(JSON.pretty_generate({ '$ref': "swagger.json#/definitions/#{key}" })) end end
테스트는 다음과 같습니다.
describe 'GET /users' do it 'List all users' do get '/users' expect_status(200) expect(result[:users][0]).to match_json_schema('User') end end
이런 식으로 테스트를 작성하는 것은 매우 편리합니다. 특히 IDE가 테스트 실행 및 디버깅을 지원하는 경우(예: WebStorm, RubyMine 및 Visual Studio). 이렇게 하면 다른 소프트웨어 사용을 피할 수 있으며 전체 API 개발 주기는 세 단계로 제한됩니다.
- tinyspec 파일에서 사양을 디자인합니다.
- 추가/편집된 엔드포인트에 대한 전체 테스트 세트 작성.
- 테스트를 만족시키는 코드를 구현합니다.
2. 입력 데이터 검증
OpenAPI는 응답 형식뿐만 아니라 입력 데이터도 설명합니다. 이를 통해 런타임 시 사용자가 보낸 데이터를 검증하고 일관성 있고 안전한 데이터베이스 업데이트를 보장할 수 있습니다.
사용자 레코드의 패치와 업데이트가 허용되는 모든 사용 가능한 필드를 설명하는 다음 사양이 있다고 가정해 보겠습니다.
# user.models.tinyspec UserUpdate !{name?, age?: i} # users.endpoints.tinyspec PATCH /users/:id {user: UserUpdate} => {success: b}
이전에는 테스트 내 유효성 검사를 위한 플러그인을 살펴보았지만 더 일반적인 경우에는 ajv(npm) 및 json-schema(rubygem) 유효성 검사 모듈이 있습니다. 이를 사용하여 유효성 검사가 포함된 컨트롤러를 작성해 보겠습니다.
Node.js(코아)
이것은 Express의 후속 제품인 Koa의 예입니다. 그러나 동등한 Express 코드는 비슷해 보일 것입니다.
import Router from 'koa-router'; import Ajv from 'ajv'; import { schemas } from './schemas'; const router = new Router(); // Standard resource update action in Koa. router.patch('/:id', async (ctx) => { const updateData = ctx.body.user; // Validation using JSON schema from API specification. await validate(schemas.UserUpdate, updateData); const user = await User.findById(ctx.params.id); await user.update(updateData); ctx.body = { success: true }; }); async function validate(schema, data) { const ajv = new Ajv(); if (!ajv.validate(schema, data)) { const err = new Error(); err.errors = ajv.errors; throw err; } }
이 예에서 서버는 입력이 사양과 일치하지 않으면 500 Internal Server Error
응답을 반환합니다. 이를 피하기 위해 검증자 오류를 포착하고 검증에 실패한 특정 필드에 대한 자세한 정보를 포함하는 자체 답변을 구성하고 사양을 따를 수 있습니다.
FieldsValidationError
에 대한 정의를 추가해 보겠습니다.
# error.models.tinyspec Error {error: b, message} InvalidField {name, message} FieldsValidationError < Error {fields: InvalidField[]}
이제 가능한 끝점 응답 중 하나로 나열해 보겠습니다.
# users.endpoints.tinyspec PATCH /users/:id {user: UserUpdate} => 200 {success: b} => 422 FieldsValidationError
이 접근 방식을 사용하면 클라이언트에서 잘못된 데이터가 올 때 오류 시나리오의 정확성을 테스트하는 단위 테스트를 작성할 수 있습니다.
3. 모델 직렬화
거의 모든 최신 서버 프레임워크는 어떤 방식으로든 객체 관계형 매핑(ORM)을 사용합니다. 이는 API가 사용하는 대부분의 리소스가 모델과 해당 인스턴스 및 컬렉션으로 표현됨을 의미합니다.

응답으로 보낼 이러한 엔터티에 대한 JSON 표현을 형성하는 프로세스를 직렬화 라고 합니다.
직렬화를 수행하기 위한 여러 플러그인이 있습니다. 예를 들어, Sequelize-to-json(npm),acts_as_api(rubygem) 및 jsonapi-rails(rubygem). 기본적으로 이러한 플러그인을 사용하면 JSON 개체에 포함되어야 하는 특정 모델의 필드 목록과 추가 규칙을 제공할 수 있습니다. 예를 들어 필드의 이름을 바꾸고 해당 값을 동적으로 계산할 수 있습니다.
하나의 모델에 대해 여러 가지 다른 JSON 표현이 필요하거나 개체에 중첩된 엔터티(연결)가 포함되어 있으면 더 어려워집니다. 그런 다음 상속, 재사용 및 직렬 변환기 연결과 같은 기능이 필요하기 시작합니다.
다른 모듈은 다른 솔루션을 제공하지만 다음을 고려해 보겠습니다. 사양이 다시 도움이 될 수 있습니까? 기본적으로 JSON 표현에 대한 요구 사항에 대한 모든 정보, 포함된 엔터티를 포함하여 가능한 모든 필드 조합이 이미 포함되어 있습니다. 이것은 우리가 하나의 자동화된 직렬 변환기를 작성할 수 있음을 의미합니다.
Sequelize 모델에 대해 이 작업을 지원하는 작은 npm(sequelize-serialize) 모듈을 소개하겠습니다. 모델 인스턴스 또는 배열, 필요한 스키마를 수락한 다음 이를 반복하여 직렬화된 개체를 빌드합니다. 또한 모든 필수 필드를 설명하고 연결된 엔터티에 대해 중첩된 스키마를 사용합니다.
따라서 API에서 이러한 게시물에 대한 댓글을 포함하여 블로그 게시물이 있는 모든 사용자를 반환해야 한다고 가정해 보겠습니다. 다음 사양으로 설명하겠습니다.
# models.tinyspec Comment {authorId: i, message} Post {topic, message, comments?: Comment[]} User {name, isAdmin: b, age?: i} UserWithPosts < User {posts: Post[]} # blogUsers.endpoints.tinyspec GET /blog/users => {users: UserWithPosts[]}
이제 Sequelize를 사용하여 요청을 빌드하고 위에서 설명한 사양에 정확히 일치하는 직렬화된 개체를 반환할 수 있습니다.
import Router from 'koa-router'; import serialize from 'sequelize-serialize'; import { schemas } from './schemas'; const router = new Router(); router.get('/blog/users', async (ctx) => { const users = await User.findAll({ include: [{ association: User.posts, required: true, include: [Post.comments] }] }); ctx.body = serialize(users, schemas.UserWithPosts); });
이것은 거의 마법과도 같죠?
4. 정적 타이핑
TypeScript 또는 Flow를 사용할 만큼 멋진 사람이라면 이미 "내 소중한 정적 유형은 무엇입니까?"라고 물었을 것입니다. sw2dts 또는 swagger-to-flowtype 모듈을 사용하면 JSON 스키마를 기반으로 필요한 모든 정적 유형을 생성하고 테스트, 컨트롤러 및 직렬 변환기에서 사용할 수 있습니다.
tinyspec -j sw2dts ./swagger.json -o Api.d.ts --namespace Api
이제 컨트롤러에서 유형을 사용할 수 있습니다.
router.patch('/users/:id', async (ctx) => { // Specify type for request data object const userData: Api.UserUpdate = ctx.request.body.user; // Run spec validation await validate(schemas.UserUpdate, userData); // Query the database const user = await User.findById(ctx.params.id); await user.update(userData); // Return serialized result const serialized: Api.User = serialize(user, schemas.User); ctx.body = { user: serialized }; });
그리고 테스트:
it('Update user', async () => { // Static check for test input data. const updateData: Api.UserUpdate = { name: MODIFIED }; const res = await request.patch('/users/1', { user: updateData }); // Type helper for request response: const user: Api.User = res.body.user; expect(user).to.be.validWithSchema(schemas.User); expect(user).to.containSubset(updateData); });
생성된 유형 정의는 API 프로젝트뿐만 아니라 클라이언트 애플리케이션 프로젝트에서도 API와 함께 작동하는 함수의 유형을 설명하는 데 사용할 수 있습니다. (Angular 개발자는 이에 대해 특히 만족할 것입니다.)
5. 쿼리 문자열 유형 캐스팅
어떤 이유로 API가 application/json
대신 application/x-www-form-urlencoded
MIME 유형의 요청을 사용하는 경우 요청 본문은 다음과 같습니다.
param1=value¶m2=777¶m3=false
쿼리 매개변수(예: GET
요청)도 마찬가지입니다. 이 경우 웹 서버는 자동으로 유형을 인식하지 못합니다. 모든 데이터는 문자열 형식이므로 구문 분석 후에 다음 개체를 얻습니다.
{ param1: 'value', param2: '777', param3: 'false' }
이 경우 요청은 스키마 유효성 검사에 실패하므로 올바른 매개변수의 형식을 수동으로 확인하고 올바른 유형으로 캐스트해야 합니다.
추측할 수 있듯이 사양의 좋은 오래된 스키마를 사용하여 이를 수행할 수 있습니다. 이 끝점과 다음 스키마가 있다고 가정해 보겠습니다.
# posts.endpoints.tinyspec GET /posts?PostsQuery # post.models.tinyspec PostsQuery { search, limit: i, offset: i, filter: { isRead: b } }
이 엔드포인트에 대한 요청은 다음과 같습니다.
GET /posts?search=needle&offset=10&limit=1&filter[isRead]=true
모든 매개변수를 필수 유형으로 캐스팅하는 castQuery
함수를 작성해 보겠습니다.
function castQuery(query, schema) { _.mapValues(query, (value, key) => { const { type } = schema.properties[key] || {}; if (!value || !type) { return value; } switch (type) { case 'integer': return parseInt(value, 10); case 'number': return parseFloat(value); case 'boolean': return value !== 'false'; default: return value; } }); }
npm(cast-with-schema) 모듈에서 중첩된 스키마, 배열 및 null
유형을 지원하는 보다 완전한 구현을 사용할 수 있습니다. 이제 코드에서 사용하겠습니다.
router.get('/posts', async (ctx) => { // Cast parameters to expected types const query = castQuery(ctx.query, schemas.PostsQuery); // Run spec validation await validate(schemas.PostsQuery, query); // Query the database const posts = await Post.search(query); // Return serialized result ctx.body = { posts: serialize(posts, schemas.Post) }; });
4줄의 코드 중 3줄은 사양 스키마를 사용합니다.
모범 사례
여기에서 따를 수 있는 모범 사례가 많이 있습니다.
별도의 스키마 생성 및 편집 사용
일반적으로 서버 응답을 설명하는 스키마는 입력을 설명하고 모델을 만들고 편집하는 데 사용되는 스키마와 다릅니다. 예를 들어 POST
및 PATCH
요청에서 사용 가능한 필드 목록은 엄격하게 제한되어야 하며 PATCH
에는 일반적으로 모든 필드가 선택 사항으로 표시되어 있습니다. 응답을 설명하는 스키마는 보다 자유로운 형식일 수 있습니다.
CRUDL 끝점을 자동으로 생성할 때 tinyspec은 New
만들기 및 Update
접미사를 사용합니다. User*
스키마는 다음과 같은 방식으로 정의할 수 있습니다.
User {id, email, name, isAdmin: b} UserNew !{email, name} UserUpdate !{email?, name?}
이전 스키마의 재사용 또는 상속으로 인한 우발적인 보안 문제를 방지하려면 다른 작업 유형에 대해 동일한 스키마를 사용하지 마십시오.
스키마 명명 규칙 준수
동일한 모델의 내용은 다른 끝점에 따라 다를 수 있습니다. 스키마 이름에 With*
및 For*
접미사를 사용하여 차이점과 목적을 표시합니다. tinyspec에서 모델은 서로 상속할 수도 있습니다. 예를 들어:
User {name, surname} UserWithPhotos < User {photos: Photo[]} UserForAdmin < User {id, email, lastLoginAt: d}
접미사는 다양하고 결합될 수 있습니다. 그들의 이름은 여전히 본질을 반영하고 문서를 더 읽기 쉽게 만들어야 합니다.
클라이언트 유형에 따라 끝점 분리
종종 동일한 엔드포인트가 클라이언트 유형 또는 요청을 보낸 사용자의 역할에 따라 다른 데이터를 반환합니다. 예를 들어, GET /users
및 GET /messages
엔드포인트는 모바일 애플리케이션 사용자와 백오피스 관리자에 대해 크게 다를 수 있습니다. 엔드포인트 이름 변경은 오버헤드가 될 수 있습니다.
동일한 끝점을 여러 번 설명하려면 경로 뒤에 괄호 안에 해당 유형을 추가할 수 있습니다. 이것은 또한 태그 사용을 쉽게 만듭니다. 끝점 문서를 그룹으로 분할하며, 각 그룹은 특정 API 클라이언트 그룹을 위한 것입니다. 예를 들어:
Mobile app: GET /users (mobile) => UserForMobile[] CRM admin panel: GET /users (admin) => UserForAdmin[]
REST API 문서 도구
tinyspec 또는 OpenAPI 형식으로 사양을 얻은 후 HTML 형식으로 멋진 문서를 생성하고 게시할 수 있습니다. 이것은 API를 사용하는 개발자를 행복하게 할 것이며 REST API 문서 템플릿을 손으로 채우는 것보다 확실히 낫습니다.
앞서 언급한 클라우드 서비스 외에도 OpenAPI 2.0을 모든 정적 호스팅에 배포할 수 있는 HTML 및 PDF로 변환하는 CLI 도구가 있습니다. 여기 예시들이 있습니다 :
- bootprint-openapi(npm, tinyspec에서 기본적으로 사용됨)
- swagger2markup-cli(jar, 사용 예가 있으며 tinyspec Cloud에서 사용됨)
- redoc-cli(npm)
- 위더신(npm)
더 많은 예가 있습니까? 댓글에서 공유하세요.
안타깝게도 1년 전에 출시되었음에도 불구하고 OpenAPI 3.0은 여전히 제대로 지원되지 않으며 클라우드 솔루션과 CLI 도구 모두에서 이를 기반으로 하는 적절한 문서 예제를 찾지 못했습니다. 같은 이유로 tinyspec은 아직 OpenAPI 3.0을 지원하지 않습니다.
GitHub에 게시
문서를 게시하는 가장 간단한 방법 중 하나는 GitHub 페이지입니다. 저장소 설정에서 /docs
폴더에 대한 정적 페이지 지원을 활성화하고 이 폴더에 HTML 문서를 저장하십시오.
각 커밋 후에 문서를 자동으로 업데이트하기 위해 scripts/package.json
파일에서 tinyspec 또는 다른 CLI 도구를 통해 문서를 생성하는 명령을 추가할 수 있습니다.
"scripts": { "docs": "tinyspec -h -o docs/", "precommit": "npm run docs" }
지속적인 통합
문서 생성을 CI 주기에 추가하고 이를 환경 또는 API 버전(예: /docs/2.0
, /docs/stable
및 /docs/staging
)에 따라 다른 주소로 Amazon S3에 게시할 수 있습니다.
타이니 스펙 클라우드
tinyspec 구문이 마음에 든다면 tinyspec.cloud의 얼리 어답터가 될 수 있습니다. 우리는 이를 기반으로 하는 클라우드 서비스와 다양한 템플릿 선택과 개인화된 템플릿 개발 기능을 갖춘 문서의 자동화된 배포를 위한 CLI를 구축할 계획입니다.
REST 사양: 놀라운 신화
REST API 개발은 아마도 현대 웹 및 모바일 서비스 개발에서 가장 즐거운 프로세스 중 하나일 것입니다. 브라우저, 운영 체제 및 화면 크기 동물원이 없으며 모든 것이 손끝에서 완전히 제어됩니다.
이 프로세스는 자동화 및 최신 사양에 대한 지원으로 훨씬 쉬워졌습니다. 내가 설명한 접근 방식을 사용하는 API는 잘 구조화되고 투명하며 신뢰할 수 있습니다.
결론은, 우리가 신화를 만들고 있다면 왜 그것을 놀라운 신화로 만들지 않겠습니까?