8. !
"
Consumer Provider
HTTP Client HTTP Server
요청(Request)
응답(Response)
REST API a.k.a RESTful or Web API or HTTP API
자원(RESOURCE) - URI
행위(Verb) - HTTP Method
표현(Representations)
HTTP 프로토콜 기반
웹 기술이 가진 신뢰성, 확장성을 그대로 이어받아 분산 컴퓨팅에 적합한 API 만들수 있는 방법으로 자원(RESOURCE) - URI, 행위(Verb) - HTTP METHOD, 표현(Representations)으로 구성되어 있다.
서비스 제공자 장애나 네트워크 지연 등을 고려해야 한다.
9. !
"
Consumer Provider
RPC Stub RPC Server
요청(Request)
응답(Response)
Shared
Library
원격 프로시저 호출Remote Procedure Call; RPC
로컬 프로시저나 메소드를 호출하듯 원격 시스템에 서비스를 사용할 수 있는 방법으로 네트워크를 이용한다는 인지도 없이 원격 시스템에 서비스를 쉽게 통합하고, 사용할 수 있다.
하지만 두 시스템간 강결합이 일어난다. 오래된 기술 같지만 구글에서 공개한 gRPC의 경우 강력한 성능과 다양한 플랫폼을 지원하는 도구로 최근 큰 관심을 이끌고 있다.
23. ❯ create-api generate schema.json --config-option module=PetstoreKit --output PetstoreKit
Generating code for schema.json...
import Foundation
import Get
import PetstoreKit
public class PetstoreWebClient {
let api: APIClient
public init() {
self.api = APIClient(
baseURL: URL(string: "https://letswift.kr/2022/petstore")
)
}
public func findPets(by status: Paths.Pet.FindByStatus.Status) async throws -> [Pet] {
let request = Paths.pet.findByStatus.get(status: status)
let response = try await api.send(request)
return response.value
}
}
IDL repo
swift package
CreateAPI
CreateAPI로 Swift 코드 생성하기
①
Using the Code
②
24. import Foundation
import PetstoreKit
import SwiftGRPC
public class PetstoreGrpcClient {
let client: PetstoreServiceClient
public init() {
self.client = PetstoreServiceClient.init(
address: "letswift.kr:80", secure: false
)
}
public func findPets(by status: FindPetsByStatusRequestStatus) async throws -> [Pet] {
let request = FindPetsByStatusRequest.init(status: status)
let response = try await client.findPetsByStatus(request)
return response.pets
}
}
IDL repo
petstore.grpc.swift,
petsotre.pb.swift
gRPC Swift
gRPC로 Swift 코드 생성하기
Using the Code
②
❯ protoc schema.proto
--swift_out=Visibility=Public:./PetstoreKit/Sources
--grpc-swift_out=Visibility=Public,Client=true,Server=false:./PetstoreKit/Sources
①
26. Client GraphQL API
#
!
$
%
{
"user": {
"id": 2022,
"name": "Arawn Park",
"address": {
"city": "Firenze",
"street": "Piazza del Duomo"
}
}
}
query {
user (id: 2022) {
id
name
address {
city
street
}
}
}
HTTP Request
HTTP Response
쿼리 스키마 확인이 가능한 GraphQL
27. !
"
#
Consumer Provider
Unit tests Unit tests
Required interactions are
captured into a contract
between systems
Contract is shared amongst teams to enable
collaboration, using tools like Pactflow
Requests in contract replayed
against provider API and verified
against consumer s expectations
Consumer unit tests
its behaviour against
provider mock
Provider tests mock out
any other systems, so it
can be tested in isolation
①
②
③
④
⑤
계약 테스트Contract Test하기
28. Pactflow로 하는 계약 테스트
!
"
Consumer
Provider
&
'
(
GET /users/2022
{
"user": {
"id": 2022,
"name": "Arawn Park"
}
}
GET /users/2022
{
"user": {
"id": 2022,
"name": "Arawn Park"
}
}
Testing a consumer using a Pact mock provider
①
mock provider
simulated consumer
Testing a provider using a Pact simulated consumer
②
Contract
29. 우린 같은 곳을
바라 보고 있나요?
https://imaggeo.egu.eu/view/1251/
30. 정세영, 이동건, 강대규, 그리고 당근마켓 iOS 챕터
https://flic.kr/p/29cXbAf
32. 참고자료
- The Design of Web APIs
- Create API
- gRPC Swift
- Next Generation Client APIs in Envoy Mobile
- Move Fast and Consumer Driven Contract Test Things
- How Pact contract testing works