SlideShare una empresa de Scribd logo
1 de 58
RESTful API 제대로 개발하기
by Appkr
1
남들이 쓰지 않는 API라면?
RESTful 하지 않아도 된다. 사실 아무렇게나 만들어도 상관없다.
나만 이해하면 되니까… 그런데 바꾸어 말하면, 이런 API는 아무도 안쓴다는 얘기.
2
// RPC style request. What API client faces
http://fakesvc.com/getClient.php?name=chris
// API Server
<?php
...
$name = $_GET['name'];
$result = $conn->query("SELECT * FROM clients WHERE name='{$name}'");
while ($row = $result->fetch_object()) $payload[] = $row;
header('Content-Type: application/json; charset=utf-8');
echo json_encode($payload);
대충 개발하면 이렇게 된다!
What the fxxx…
오늘의 고객을 만족시키면 내일을 위한 영업은 필요 없다.
3
오늘 이후, 우리는
1. REST 원칙을 (대략) 이해한다.
2. 남의 API를 (대략) 읽을 수 있다.
3. RESTful API를 (대략) 만들 수 있다.
4
그런데, API의 본질은 무엇일까요?
Separate of Concern
Decoupling
5
그럼, Web API의 본질은 무엇일까요?
Know who the API clients are. So various platforms, various languages
Decoupling + Platform Agnostic
6
REST Fundamental
7
REST의 역사
Representational State Transfer
8
웹(HTTP)의 창시자 중의 한사람인
Roy Fielding의 2000년 논문에서 소개
“현재 웹 서비스들의 HTTP의 본래 의도 및
우수성을 제대로 활용하지 못하고 있다”고 판단
웹의 장점을 최대한 활용할 수 있는
네트워크 기반의 아키텍처로 REST를 제안
http://bcho.tistory.com/953
REST의 특징
9
Uniform Interface (=Platform Agnostic)
Stateless
Cacheable
Self Descriptiveness
Client-Server Architecture
http://bcho.tistory.com/953
WHAT IS GOOD API? WHY REST?
10
Easy to learn, Easy to use,
Hard to misuse
+
Performance, Scalability, Reusability, Evolvability, Documentation
IS REST REALLY EASY TO
IMPLEMENTERS?
11
REST is &*#!(@$^& Hard
REST can be easy
(if you follow some guidelines)
HOW TO LEARN REST
12
RESTful API Design Principles
(by Roy Fielding, Leonard Richardson, Martin Fowler, HTTP specification)
Web Giants 복붙
(Github, Twitter, Google, Facebook, …)
IT’S JUST A GUIDELINE! NOT A SPEC!
13
REST is an architectural style
NO strict rule (~ful)
RICHARDSON MATURITY MODEL
http://martinfowler.com/articles/richardsonMaturityModel.html
14
NOT RESTful
Level 1: Resource (API endpoints)
Level 2: HTTP Conformance
Level 3: HATEOAS
(Resource Discoverability)
GLORY OF REST
HOW THE CLIENT & SERVER COMMUNICATE
15
Client Server
CREATE /things thingX, thingY, thingZ
201 CREATED things 13 was created
READ /things/13
200 OK thingX, thingY, thingZ
UPDATE /things/13
200 OK thingX2, thingY, thingZ
READ /things/no-exist
404 Not Found
Notice that pattern (COLOR):
A set of commands (method)
performed on things (resource)
generates responses (message).
This is the foundation of
a REST API.
REpresentational State Transfer
REST 101
3 Pillars of REST
16
Method, Resource, Message
POST /things 201 CREATED
{“name”: “teapot”}
METHOD
CRUD – Create, Retrieve(Read), Update, Delete
17
HTTP
Method
Action Endpoints
Controller
Method
(in Laravel)
Description Idem-
POST Create /things store()
Create a new
resource No
GET/HEAD Read /things index()
Get a collection
of resource Yes
GET/HEAD Read /things/a1b2 show($id)
Get the specified
specified
resource
Yes
PUT/PATCH Update /things/a1b2 update($id)
Update the
specified
resource
Yes
DELETE Delete /things/a1b2 delete($id)
Delete the
specified
resource
Yes
METHOD - ANTI-PATTERN
Tunneling though GET or POST
18
GET http://fakehost/things?method=update&name=teapot (X)
POST http://fakehost/things (X)
{
"getUser" : {"id": "teapot"}
}
https://speakerdeck.com/philsturgeon/api-pain-points-lone-star-php-2015
METHOD - IDEMPOTENT
It’s about SAFENESS when a request is repeated.
$a = 4; 와 $a++;의 차이. 실패할 경우, Rollback 해야 한다.
19
RESOURCE - NOUN
API Endpoint는 동사형(Verb) 사용을 지양하고, 명사형(Noun)을 사용한다.
20
// RPC style
GET http://fakehost/getThings (X)
// RESTful style
GET http://fakehost/things (O)
// Sub Resource
GET http://fakehost/author/{username}/things (O)
RESOURCE - PLURALIZE
API Endpoint는 단수(Singular) 보다 복수형(Plural)을 사용한다.
21
GET http://fakehost/thing (X)
// Collection endpoint
GET http://fakehost/things (O)
// Instance endpoint
GET http://fakehost/things/{id} (O)
RESOURCE – CONSISTENT CASE
API Endpoint의 대소문자를 일관되게 사용한다.
22
// Google, Facebook, Twitter, Github
GET http://fakehost/snake_case
// Google, Paypal
GET http://fakehost/spinal-case
// Google
GET http://fakehost/camelCase
RESOURCE - VERSIONING
새로운 Version을 위한 Controller로 Response 분리
또는 Reverse Proxy를 이용하여 서버를 물리적으로 분리
23
// Sub domain을 쓸 수 있다면
GET http://api.fakehost/v1/things
// Sub domain을 쓸 수 없는 경우
GET http://fakehost/api/v1/things
RESOURCE – DOMAIN NAME
대형 서비스라면… API Gateway, Developer Connection, and Authentication
24
// API(=Resource) Server
http://api.{company}.com
// Developer Portal
http://developers.{company}.com
// Authentication Server
http://oauth2.{company}.com
RESOURCE – ANTI-PATTERN
NOT self-descriptive
Method와 Endpoint만 보고도 무엇을 하는 것인지 이해할 수 있어야 한다.
25
// Request
POST http://nailshop/appointmentService
<openSlotRequest date="2015-09-30" nailist="gwen"/>
// Response
HTTP/1.1 200 OK
<openSlotList>
<slot start="1400" end="1420"> … </slot>
</openSlotList>
Complex things behind the ‘?’.
Pagination, Filtering, Sorting, Searching, Partial Response
26
// Pagination
/v1/things?range=0-25
/v1/things?offset=0&limit=25
// Filtering
/v1/things?origin=jp,en&rating=4,5
// Sorting
/v1/things?sort=name&direction=asc
// Searching
/v1/things?q=lorem+dolar
/v1/?q=lorem+dolar
// Partial Response
/v1/things?fields=title,created_at
RESOURCE – QUERY STRING
REQUEST & RESPONSE – ANTI-PATTERN
<?php
class ThingsController extends Controller
{
public function index()
{
return AppThing::all();
}
}
all(); is bad – by Jeffrey Way
27
REQUEST & RESPONSE – ANTI-PATTERN
all(); is bad – by Jeffrey Way
28
1. All is bad (Pagination)
2. No way to attach meta data
3. Linking DB structure to the API output
(Hiding some field, Renaming field)
4. No way to signal Headers/response codes
(Error response, HATEOAS)
https://laracasts.com/series/incremental-api-development
REQUEST & RESPONSE – ANTI-PATTERN
Response Code (=Status Code)는 200만 있는게 아니다.
29
// AngularJS
$http.post("http://fakehost/things", {"name": "teapot"})
.then(function(response) {
if (response.status !== 200) {
throw new Error("200이 아니면 죽음을 달라");
}
});
REQUEST & RESPONSE – RESPONSE CODE
30
Code String Description
1xx All about information (Not used for API resp.)
200 OK All about success
201 Created Resource was created (Location Header)
204 No Content Success response without response body
3xx All about redirection
304 Not Modified If-Modified-Since 에 대한 응답 (Cache)
400 Bad Request All about client error
401 Unauthorized Really means UNAUTHENTICATED
403 Forbidden Really means UNAUTHORIZED
404 Not Found
405 Method Not Allowed
422 Unprocessable Entity Validation Error (406 is also acceptable)
500 Server Error
REQUEST & RESPONSE – CONTENT NEGOTIATION
Content & Language Negotiation
31
// Request
GET /v1/things HTTP/1.1
Accept: application/json
Accept-Language: ko-KR;q=0.8,en-US;q=0.6,en;q=0.4
// Response
HTTP/1.1 200 OK
Content-Type: application/json
REQUEST & RESPONSE - TRAMSFORMATION
Transformer to decouple a PRESENTATION layer from the DOMAIN layer
32
REQUEST & RESPONSE - TRANSFORMATION
Transformer to decouple PRESENTATION layer from DOMAIN layer
33
<?php
class ThingsController extends Controller
{
public function index()
{
return array_map(function($thing) {
return [
'id' => (int) $thing->id,
'meta' => ['version' => 1],
'...' => '...'
];
}, AppThing::all());
}
}
REQUEST & RESPONSE - SERIALIZATION
Serialize the response data to format it properly
34
REQUEST & RESPONSE – SERIALIZATION
league/fractal natively supports DataArraySerializer, ArraySerializer,
JsonApiSerializer
35
// DataArraySerializer
{"data":{"foo":"bar"}} // instance
{“data":[{"foo":"bar"}]} // collection
// ArraySerializer
{"foo":"bar"} // instance
{"data":{"foo":"bar"}} // collection
// JsonApiSerializer
{"data":{"type":"books","id":1,"attributes":{"foo":"bar"}}} // instance
{"data":[{"type":"books","id":1,"attributes":{"foo":"bar"}}]} //
collection
http://fractal.thephpleague.com/serializers/
REQUEST & RESPONSE – ERROR RESPONSE
BODY
Error response 는 최대한 Descriptive 하게.
DEBUG 모드에서는 Stack Trace등 디버그 정보도 출력하면 편리함.
36
// Response
{
"error": {
"code": 400,
"message": "Deliberate Error",
"dictionary": "http: //developers.fakehost/v1/errors/400"
},
"debug": {
"line": 42,
"file": "..."
}
}
REQUEST & RESPONSE - HATEOAS
Hypermedia As The Engine Of Application State. In case of normal HTML
response, client can navigate sub resources through set of links.
37
REQUEST & RESPONSE - HATEOAS
API 사용자가 길을 잃지 않도록 Sub Resource(Nested)에 대한 링크를 포함.
38
// Response
{
"data": [
{
"id": 100,
"title": "Quia sunt culpa numquam blanditiis...",
"link": {
"rel": "self",
"href": "http://fakehost/v1/things/100"
}
},
{"...": "..."}
]
}
appkr/fractal
39
league/fractal Wrapper for Laravel5/Lumen5
Focuses on RESPONSE(=View layer) of the API response
HOW TO INSTALL
// composer.json
"require": {
"appkr/fractal": "0.5.*",
"league/fractal": "@dev",
}
$ composer update
// config/app.php
'providers'=> [
AppkrFractalApiServiceProvider::class,
]
40
HOW TO USE
41
// app/Http/routes.php
Route::resource(
'things',
ThingsController::class,
['except' => ['create', 'edit']]
);
// app/Http/Controllers/ThingsController
class ThingsController extends Controller
{
public function index(AppkrFractalHttpResponse $response)
{
return $response->setMeta(['version' => 1])->withPagination(
AppThing::latest()->paginate(25),
new AppTransformersThingTransformer
);
}
}
HOW TO USE
42
// Response
{
"data": [
{
"id": 1,
"title": "Quia sunt culpa numquam blanditiis.",
"created_at": "2015-09-19T08:07:55+0000",
"link": {
"rel": "self",
"href": "http://localhost:8000/v1/things/1?include=author"
},
"author": "landen08"
},
{
"...": "..."
}
],
"meta": {
"version": 1,
"pagination": {
"total": 106,
"count": 25,
"per_page": 25,
"current_page": 1,
"total_pages": 5,
"links": {
"next": "http://localhost:8000/v1/things/?page=2"
}
}
}
}
HOW TO ACTIVATE & TEST EXAMPLES
Database migrations and seeder, Routes definition, Eloquent Model and
corresponding Controller, FormRequest, Transformer, Integration Test
43
// Activate examples at vendor/appkr/fractal/src/ApiServiceProvider.php
$this->publishExamples();
// Migrate/seed tables at a console
$ php artisan migrate --path="vendor/appkr/fractal/database/migrations"
$ php artisan db:seed —class="AppkrFractalExampleDatabaseSeeder"
// Boot up a local server
$ php artisan serve
// Request to the endpoint using CURL or POSTMAN
GET http://localhost:8000/v1/things
GET http://localhost:8000/v1/things/{id}
POST http://localhost:8000/v1/things
PUT http://localhost:8000/v1/things/{id} // Method overriding required
DELETE http://localhost:8000/v1/things/{id} // Method overriding
required
떡밥!!!
스스로 찾아 더 공부해 보세요
44
AUTO-INCREMENT ID (BAD DESIGN)
zackkitzmiller/timy, jenssengers/optimus
45
인증과 권한부여가 없는 식당예약 API를 호출했더니,
내 식당 예약이 /reservations/15로 리턴됨.
“덕질”
/reservations/14 요청해 보실거죠?
여기까지.. 더하면 잡혀 가요.
구현 참고 http://laravel.io/bin/JxXyW
AUTO-INCREMENT ID (BAD DESIGN)
// app/Providers/AppServiceProviders.php
public function register() {
$this->app->singleton(Optimus::class, function () {
return new JenssegersOptimus(1118129599, 664904255, 1002004882);
});
}
// app/BaseModel.php
abstract class BaseModel extends Model {
public function getIdAttribute($value) {
return app(Optimus::class)->encode($value);
}
public static function find($id, $columns = ['*']) {
$transformedId = app(JenssegersOptimusOptimus::class)->decode($id);
return static::query()->find($transformedId, $columns);
}
}
// app/SomeModel.php
class SomeModel extends BaseModel { }
// app/Http/Controllers/SomeController.php
public function show($id) {
return SomeModel::find($id);
}
46
AUTHENTICATION
laravel/socialite, league/oauth2-server, tymon/jwt-auth
47
Access Control, Throttling, …
등을 위해 필요합니다.
1st/3rd Party Oauth2, JWT 이용
SSL 권장
AUTHENTICATION
3rd Party Auth/JWT 구현 참고 appkr/rest
// app/Http/Controllers/Api/Auth/SocialController.php
protected function handleProviderCallback($provider) {
$user = Socialite::with($provider)->user();
return $user = $this->repo->firstOrCreate([
'...',
'email' => $user->getEmail(),
'avatar' => $user->getAvatar()
], $this);
}
// app/Http/Controllers/Api/Auth/SessionController.php
protected function respondLoginSuccess(AuthRequest $request, User $user) {
$meta = $this->buildUserMeta($user);
return $this->response->setMeta(['token' => JWTAuth::fromUser($user)])->success();
}
// app/Http/Controllers/Api/ThingsController.php
public function __construct() {
$this->middleware('jwt.auth', ['except' => ['index', 'show']]);
}
// Request
POST /v1/things
Authorization: Bearer header.payload.signature
48
AUTHORIZATION
bican/roles, cartalyst/sentinel, graham-campbell/throttle
49
RBAC + Laravel Native
API의 공평한 분배를 통한 정의사회 구현
Data가 재산인 시대에 Data API로 돈 벌려면 Throttle은 필수
Object
User:
teapot
Member
Admin
Guest
Roles
Read all resource
CRUD against my
resource
Permissions
http://bcho.tistory.com/955
AUTHORIZATION
RBAC, Throttle 구현 참고 appkr/rest
// app/Http/Middleware/RoleMiddleware.php
public function handle($request, Closure $next, $role) {
if (! $request->user()->is($role)) {
if ($request->ajax() or $request->is('v1/*')) {
throw new Exception('Forbidden', 403);
}
}
return $next($request);
}
// app/Http/Middleware/ThrottleMiddleware.php
public function handle($request, Closure $limit = 10, $time = 60) {
if (! $this->throttle->attempt($request, $limit, $time))) {
throw new TooManyRequestHttpException($time * 60, 'Rate limit exceeded.');
}
return $next($request);
}
// app/Http/Controllers/Api/ThingsController.php
public function __construct() {
$this->middleware('role:member', ['except' => ['index', 'show']]);
$this->middleware('throttle:10,1');
}
50
CORS
Reverse Proxy가 최선. 차선은 Access-Control-Allow-Origin HTTP Header
조작: Barryvdh/laravel-cors, asm89/stack-cors. 폭탄 넘기기: jsonp
51
API 서버로 Ajax 요청을 하는 JavaScript를 실행하는 도메
인과, API 서버의 도메인이 다르면 에러납니다. Same
Origin Policy
Scheme, Port도 같아야 해요!!!
Browser
http://fakesvc.com http://api.fakehost.com
Load JS API Call via Ajax (X)
http://bcho.tistory.com/955
CACHING
Application(Domain) Level의 Cache
Cache에 적재해 놓고, Create, Update, Delete 액션이 발생하면 Cache 삭제
52
// app/Http/Controllers/v1/ThingsController.php
class ThingsController extends Controller
{
public function index()
{
Cache::get('things', function () {
return AppThings::all();
});
}
public function store()
{
...
event(new AppEventsClearCache('things'));
}
}
CACHING
Application(Domain) Level의 Cache
Cache에 적재해 놓고, Create, Update, Delete 액션이 발생하면 Cache 삭제
53
// app/Events/ClearCache.php
public function __construct($tags)
{
$this->tags = $tags;
}
// app/Listeners/CacheListener.php
public function handle(ClearCache $event)
{
if (!is_array($event->tags)) {
return $this->cache->tags($event->tags)->flush();
}
foreach ($event->tags as $tag) {
$this->cache->tags($tag)->flush();
}
return;
}
CACHING
ETAG/If-None-Match 또는 Last-Modified/If-Modified-Since 를 이용한 Cache.
API 소비자는 Web Browser만 있는게 아니다.
54
Client Server
GET /v1/things
https://en.wikipedia.org/wiki/HTTP_ETag
200 OK
ETag: 686897696a7c876b7e
Cache Storage
(key: 6868..) Later ….
GET /v1/things
If-None-Match: 686897696a7c876b7e
304 Not Modified
API MODELING LANGUAGE/SERVICE
http://raml.org/, https://apiblueprint.org/, https://apiary.io/
55
REST API Modeling Language
(혼자 개발하기에) 저는 안 써 봤습니다;;;
(팀웍하신다면) 한번 써 보세요.
56
• http://www.slideshare.net/landlessness/teach-a-dog-to-rest,
https://www.youtube.com/watch?v=QpAhXa12xvU
• https://laracasts.com/series/incremental-api-development
FURTHER READINGS
RESTful API에 대해 더 공부하고 싶거나,
Laravel에서 API 구현 방안에 대해 더 공부하고 싶으시다면..
Summary
57
1. REST 원칙을 이해한다.
Method, Resource, Message(Response)
2. 남의 것을 읽을 수 있다.
API Document를 모두 읽을 필요는 없다.
3. 내 것을 만들 수 있다.
직접, appkr/fractal, dingo/api 이용.
Email: juwonkim@me.com
Facebook: juwonkimatmedotcom
Github: appkr
58

Más contenido relacionado

La actualidad más candente

HTTP Status Codes Cheat Sheet: An Exhaustive List
HTTP Status Codes Cheat Sheet: An Exhaustive ListHTTP Status Codes Cheat Sheet: An Exhaustive List
HTTP Status Codes Cheat Sheet: An Exhaustive ListMainstreethost
 
Web api crud operations
Web api crud operationsWeb api crud operations
Web api crud operationsEyal Vardi
 
Understanding REST APIs in 5 Simple Steps
Understanding REST APIs in 5 Simple StepsUnderstanding REST APIs in 5 Simple Steps
Understanding REST APIs in 5 Simple StepsTessa Mero
 
REST: From GET to HATEOAS
REST: From GET to HATEOASREST: From GET to HATEOAS
REST: From GET to HATEOASJos Dirksen
 
Intro to React
Intro to ReactIntro to React
Intro to ReactTroy Miles
 
REST API and CRUD
REST API and CRUDREST API and CRUD
REST API and CRUDPrem Sanil
 
Understanding REST
Understanding RESTUnderstanding REST
Understanding RESTNitin Pande
 
Time based CAPTCHA protected SQL injection through SOAP-webservice
Time based CAPTCHA protected SQL injection through SOAP-webserviceTime based CAPTCHA protected SQL injection through SOAP-webservice
Time based CAPTCHA protected SQL injection through SOAP-webserviceFrans Rosén
 
OWASP Top 10 API Security Risks
OWASP Top 10 API Security RisksOWASP Top 10 API Security Risks
OWASP Top 10 API Security RisksIndusfacePvtLtd
 
CSRF Attack and Its Prevention technique in ASP.NET MVC
CSRF Attack and Its Prevention technique in ASP.NET MVCCSRF Attack and Its Prevention technique in ASP.NET MVC
CSRF Attack and Its Prevention technique in ASP.NET MVCSuvash Shah
 
Mongoose: MongoDB object modelling for Node.js
Mongoose: MongoDB object modelling for Node.jsMongoose: MongoDB object modelling for Node.js
Mongoose: MongoDB object modelling for Node.jsYuriy Bogomolov
 
REST-API introduction for developers
REST-API introduction for developersREST-API introduction for developers
REST-API introduction for developersPatrick Savalle
 

La actualidad más candente (20)

API Basics
API BasicsAPI Basics
API Basics
 
Building Advanced XSS Vectors
Building Advanced XSS VectorsBuilding Advanced XSS Vectors
Building Advanced XSS Vectors
 
Web api
Web apiWeb api
Web api
 
HTTP Status Codes Cheat Sheet: An Exhaustive List
HTTP Status Codes Cheat Sheet: An Exhaustive ListHTTP Status Codes Cheat Sheet: An Exhaustive List
HTTP Status Codes Cheat Sheet: An Exhaustive List
 
Rest API
Rest APIRest API
Rest API
 
Web api crud operations
Web api crud operationsWeb api crud operations
Web api crud operations
 
Introdução APIs RESTful
Introdução APIs RESTfulIntrodução APIs RESTful
Introdução APIs RESTful
 
Understanding REST APIs in 5 Simple Steps
Understanding REST APIs in 5 Simple StepsUnderstanding REST APIs in 5 Simple Steps
Understanding REST APIs in 5 Simple Steps
 
Api security
Api security Api security
Api security
 
REST: From GET to HATEOAS
REST: From GET to HATEOASREST: From GET to HATEOAS
REST: From GET to HATEOAS
 
Curl Tutorial
Curl Tutorial Curl Tutorial
Curl Tutorial
 
Intro to React
Intro to ReactIntro to React
Intro to React
 
REST API and CRUD
REST API and CRUDREST API and CRUD
REST API and CRUD
 
Understanding REST
Understanding RESTUnderstanding REST
Understanding REST
 
Rest api and-crud-api
Rest api and-crud-apiRest api and-crud-api
Rest api and-crud-api
 
Time based CAPTCHA protected SQL injection through SOAP-webservice
Time based CAPTCHA protected SQL injection through SOAP-webserviceTime based CAPTCHA protected SQL injection through SOAP-webservice
Time based CAPTCHA protected SQL injection through SOAP-webservice
 
OWASP Top 10 API Security Risks
OWASP Top 10 API Security RisksOWASP Top 10 API Security Risks
OWASP Top 10 API Security Risks
 
CSRF Attack and Its Prevention technique in ASP.NET MVC
CSRF Attack and Its Prevention technique in ASP.NET MVCCSRF Attack and Its Prevention technique in ASP.NET MVC
CSRF Attack and Its Prevention technique in ASP.NET MVC
 
Mongoose: MongoDB object modelling for Node.js
Mongoose: MongoDB object modelling for Node.jsMongoose: MongoDB object modelling for Node.js
Mongoose: MongoDB object modelling for Node.js
 
REST-API introduction for developers
REST-API introduction for developersREST-API introduction for developers
REST-API introduction for developers
 

Destacado

SOAP 기반/ RESTful기반 웹서비스 비교
SOAP 기반/ RESTful기반 웹서비스 비교SOAP 기반/ RESTful기반 웹서비스 비교
SOAP 기반/ RESTful기반 웹서비스 비교seungdols
 
SOAP REST 이해
SOAP REST 이해SOAP REST 이해
SOAP REST 이해Jake Yoon
 
REST API 디자인 개요
REST API 디자인 개요REST API 디자인 개요
REST API 디자인 개요nexusz99
 
생활코딩 oauth 소개
생활코딩 oauth 소개생활코딩 oauth 소개
생활코딩 oauth 소개Binseop Ko
 
테스터가 말하는 테스트코드 작성 팁과 사례
테스터가 말하는 테스트코드 작성 팁과 사례테스터가 말하는 테스트코드 작성 팁과 사례
테스터가 말하는 테스트코드 작성 팁과 사례SangIn Choung
 
테스트자동화 성공전략
테스트자동화 성공전략테스트자동화 성공전략
테스트자동화 성공전략SangIn Choung
 
2013 빅데이터 및 API 기술 현황과 전망- 윤석찬
2013 빅데이터 및 API 기술 현황과 전망- 윤석찬2013 빅데이터 및 API 기술 현황과 전망- 윤석찬
2013 빅데이터 및 API 기술 현황과 전망- 윤석찬Channy Yun
 
The Future of Everything
The Future of EverythingThe Future of Everything
The Future of EverythingMichael Ducy
 
RPC에서 REST까지 간단한 개념소개
RPC에서 REST까지 간단한 개념소개RPC에서 REST까지 간단한 개념소개
RPC에서 REST까지 간단한 개념소개Wonchang Song
 

Destacado (10)

SOAP 기반/ RESTful기반 웹서비스 비교
SOAP 기반/ RESTful기반 웹서비스 비교SOAP 기반/ RESTful기반 웹서비스 비교
SOAP 기반/ RESTful기반 웹서비스 비교
 
SOAP REST 이해
SOAP REST 이해SOAP REST 이해
SOAP REST 이해
 
REST API 디자인 개요
REST API 디자인 개요REST API 디자인 개요
REST API 디자인 개요
 
RESTful API
RESTful APIRESTful API
RESTful API
 
생활코딩 oauth 소개
생활코딩 oauth 소개생활코딩 oauth 소개
생활코딩 oauth 소개
 
테스터가 말하는 테스트코드 작성 팁과 사례
테스터가 말하는 테스트코드 작성 팁과 사례테스터가 말하는 테스트코드 작성 팁과 사례
테스터가 말하는 테스트코드 작성 팁과 사례
 
테스트자동화 성공전략
테스트자동화 성공전략테스트자동화 성공전략
테스트자동화 성공전략
 
2013 빅데이터 및 API 기술 현황과 전망- 윤석찬
2013 빅데이터 및 API 기술 현황과 전망- 윤석찬2013 빅데이터 및 API 기술 현황과 전망- 윤석찬
2013 빅데이터 및 API 기술 현황과 전망- 윤석찬
 
The Future of Everything
The Future of EverythingThe Future of Everything
The Future of Everything
 
RPC에서 REST까지 간단한 개념소개
RPC에서 REST까지 간단한 개념소개RPC에서 REST까지 간단한 개념소개
RPC에서 REST까지 간단한 개념소개
 

Similar a RESTful API 제대로 만들기

PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applicationselliando dias
 
Tk2323 lecture 9 api json
Tk2323 lecture 9   api jsonTk2323 lecture 9   api json
Tk2323 lecture 9 api jsonMengChun Lam
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and PythonPiXeL16
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applicationselliando dias
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Elena Kolevska
 
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...King Foo
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram VaswaniCreating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswanivvaswani
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Real-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @MoldcampReal-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @MoldcampAlexei Gorobets
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
Federico Feroldi - Scala microservices
Federico Feroldi - Scala microservicesFederico Feroldi - Scala microservices
Federico Feroldi - Scala microservicesScala Italy
 
Cakefest 2010: API Development
Cakefest 2010: API DevelopmentCakefest 2010: API Development
Cakefest 2010: API DevelopmentAndrew Curioso
 
Creating native apps with WordPress
Creating native apps with WordPressCreating native apps with WordPress
Creating native apps with WordPressMarko Heijnen
 
Create a res tful services api in php.
Create a res tful services api in php.Create a res tful services api in php.
Create a res tful services api in php.Adeoye Akintola
 

Similar a RESTful API 제대로 만들기 (20)

PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
 
Tk2323 lecture 9 api json
Tk2323 lecture 9   api jsonTk2323 lecture 9   api json
Tk2323 lecture 9 api json
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and Python
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
Fatc
FatcFatc
Fatc
 
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram VaswaniCreating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
 
Os Pruett
Os PruettOs Pruett
Os Pruett
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Real-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @MoldcampReal-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @Moldcamp
 
Advanced redux
Advanced reduxAdvanced redux
Advanced redux
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
 
Federico Feroldi - Scala microservices
Federico Feroldi - Scala microservicesFederico Feroldi - Scala microservices
Federico Feroldi - Scala microservices
 
Cakefest 2010: API Development
Cakefest 2010: API DevelopmentCakefest 2010: API Development
Cakefest 2010: API Development
 
Creating native apps with WordPress
Creating native apps with WordPressCreating native apps with WordPress
Creating native apps with WordPress
 
Create a res tful services api in php.
Create a res tful services api in php.Create a res tful services api in php.
Create a res tful services api in php.
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 

Último

%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benonimasabamasaba
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2
 
WSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AIWSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AIWSO2
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...masabamasaba
 
tonesoftg
tonesoftgtonesoftg
tonesoftglanshi9
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024VictoriaMetrics
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...masabamasaba
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...chiefasafspells
 
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...masabamasaba
 

Último (20)

%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
WSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AIWSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AI
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 

RESTful API 제대로 만들기

  • 1. RESTful API 제대로 개발하기 by Appkr 1
  • 2. 남들이 쓰지 않는 API라면? RESTful 하지 않아도 된다. 사실 아무렇게나 만들어도 상관없다. 나만 이해하면 되니까… 그런데 바꾸어 말하면, 이런 API는 아무도 안쓴다는 얘기. 2 // RPC style request. What API client faces http://fakesvc.com/getClient.php?name=chris // API Server <?php ... $name = $_GET['name']; $result = $conn->query("SELECT * FROM clients WHERE name='{$name}'"); while ($row = $result->fetch_object()) $payload[] = $row; header('Content-Type: application/json; charset=utf-8'); echo json_encode($payload);
  • 3. 대충 개발하면 이렇게 된다! What the fxxx… 오늘의 고객을 만족시키면 내일을 위한 영업은 필요 없다. 3
  • 4. 오늘 이후, 우리는 1. REST 원칙을 (대략) 이해한다. 2. 남의 API를 (대략) 읽을 수 있다. 3. RESTful API를 (대략) 만들 수 있다. 4
  • 5. 그런데, API의 본질은 무엇일까요? Separate of Concern Decoupling 5
  • 6. 그럼, Web API의 본질은 무엇일까요? Know who the API clients are. So various platforms, various languages Decoupling + Platform Agnostic 6
  • 8. REST의 역사 Representational State Transfer 8 웹(HTTP)의 창시자 중의 한사람인 Roy Fielding의 2000년 논문에서 소개 “현재 웹 서비스들의 HTTP의 본래 의도 및 우수성을 제대로 활용하지 못하고 있다”고 판단 웹의 장점을 최대한 활용할 수 있는 네트워크 기반의 아키텍처로 REST를 제안 http://bcho.tistory.com/953
  • 9. REST의 특징 9 Uniform Interface (=Platform Agnostic) Stateless Cacheable Self Descriptiveness Client-Server Architecture http://bcho.tistory.com/953
  • 10. WHAT IS GOOD API? WHY REST? 10 Easy to learn, Easy to use, Hard to misuse + Performance, Scalability, Reusability, Evolvability, Documentation
  • 11. IS REST REALLY EASY TO IMPLEMENTERS? 11 REST is &*#!(@$^& Hard REST can be easy (if you follow some guidelines)
  • 12. HOW TO LEARN REST 12 RESTful API Design Principles (by Roy Fielding, Leonard Richardson, Martin Fowler, HTTP specification) Web Giants 복붙 (Github, Twitter, Google, Facebook, …)
  • 13. IT’S JUST A GUIDELINE! NOT A SPEC! 13 REST is an architectural style NO strict rule (~ful)
  • 14. RICHARDSON MATURITY MODEL http://martinfowler.com/articles/richardsonMaturityModel.html 14 NOT RESTful Level 1: Resource (API endpoints) Level 2: HTTP Conformance Level 3: HATEOAS (Resource Discoverability) GLORY OF REST
  • 15. HOW THE CLIENT & SERVER COMMUNICATE 15 Client Server CREATE /things thingX, thingY, thingZ 201 CREATED things 13 was created READ /things/13 200 OK thingX, thingY, thingZ UPDATE /things/13 200 OK thingX2, thingY, thingZ READ /things/no-exist 404 Not Found Notice that pattern (COLOR): A set of commands (method) performed on things (resource) generates responses (message). This is the foundation of a REST API. REpresentational State Transfer
  • 16. REST 101 3 Pillars of REST 16 Method, Resource, Message POST /things 201 CREATED {“name”: “teapot”}
  • 17. METHOD CRUD – Create, Retrieve(Read), Update, Delete 17 HTTP Method Action Endpoints Controller Method (in Laravel) Description Idem- POST Create /things store() Create a new resource No GET/HEAD Read /things index() Get a collection of resource Yes GET/HEAD Read /things/a1b2 show($id) Get the specified specified resource Yes PUT/PATCH Update /things/a1b2 update($id) Update the specified resource Yes DELETE Delete /things/a1b2 delete($id) Delete the specified resource Yes
  • 18. METHOD - ANTI-PATTERN Tunneling though GET or POST 18 GET http://fakehost/things?method=update&name=teapot (X) POST http://fakehost/things (X) { "getUser" : {"id": "teapot"} } https://speakerdeck.com/philsturgeon/api-pain-points-lone-star-php-2015
  • 19. METHOD - IDEMPOTENT It’s about SAFENESS when a request is repeated. $a = 4; 와 $a++;의 차이. 실패할 경우, Rollback 해야 한다. 19
  • 20. RESOURCE - NOUN API Endpoint는 동사형(Verb) 사용을 지양하고, 명사형(Noun)을 사용한다. 20 // RPC style GET http://fakehost/getThings (X) // RESTful style GET http://fakehost/things (O) // Sub Resource GET http://fakehost/author/{username}/things (O)
  • 21. RESOURCE - PLURALIZE API Endpoint는 단수(Singular) 보다 복수형(Plural)을 사용한다. 21 GET http://fakehost/thing (X) // Collection endpoint GET http://fakehost/things (O) // Instance endpoint GET http://fakehost/things/{id} (O)
  • 22. RESOURCE – CONSISTENT CASE API Endpoint의 대소문자를 일관되게 사용한다. 22 // Google, Facebook, Twitter, Github GET http://fakehost/snake_case // Google, Paypal GET http://fakehost/spinal-case // Google GET http://fakehost/camelCase
  • 23. RESOURCE - VERSIONING 새로운 Version을 위한 Controller로 Response 분리 또는 Reverse Proxy를 이용하여 서버를 물리적으로 분리 23 // Sub domain을 쓸 수 있다면 GET http://api.fakehost/v1/things // Sub domain을 쓸 수 없는 경우 GET http://fakehost/api/v1/things
  • 24. RESOURCE – DOMAIN NAME 대형 서비스라면… API Gateway, Developer Connection, and Authentication 24 // API(=Resource) Server http://api.{company}.com // Developer Portal http://developers.{company}.com // Authentication Server http://oauth2.{company}.com
  • 25. RESOURCE – ANTI-PATTERN NOT self-descriptive Method와 Endpoint만 보고도 무엇을 하는 것인지 이해할 수 있어야 한다. 25 // Request POST http://nailshop/appointmentService <openSlotRequest date="2015-09-30" nailist="gwen"/> // Response HTTP/1.1 200 OK <openSlotList> <slot start="1400" end="1420"> … </slot> </openSlotList>
  • 26. Complex things behind the ‘?’. Pagination, Filtering, Sorting, Searching, Partial Response 26 // Pagination /v1/things?range=0-25 /v1/things?offset=0&limit=25 // Filtering /v1/things?origin=jp,en&rating=4,5 // Sorting /v1/things?sort=name&direction=asc // Searching /v1/things?q=lorem+dolar /v1/?q=lorem+dolar // Partial Response /v1/things?fields=title,created_at RESOURCE – QUERY STRING
  • 27. REQUEST & RESPONSE – ANTI-PATTERN <?php class ThingsController extends Controller { public function index() { return AppThing::all(); } } all(); is bad – by Jeffrey Way 27
  • 28. REQUEST & RESPONSE – ANTI-PATTERN all(); is bad – by Jeffrey Way 28 1. All is bad (Pagination) 2. No way to attach meta data 3. Linking DB structure to the API output (Hiding some field, Renaming field) 4. No way to signal Headers/response codes (Error response, HATEOAS) https://laracasts.com/series/incremental-api-development
  • 29. REQUEST & RESPONSE – ANTI-PATTERN Response Code (=Status Code)는 200만 있는게 아니다. 29 // AngularJS $http.post("http://fakehost/things", {"name": "teapot"}) .then(function(response) { if (response.status !== 200) { throw new Error("200이 아니면 죽음을 달라"); } });
  • 30. REQUEST & RESPONSE – RESPONSE CODE 30 Code String Description 1xx All about information (Not used for API resp.) 200 OK All about success 201 Created Resource was created (Location Header) 204 No Content Success response without response body 3xx All about redirection 304 Not Modified If-Modified-Since 에 대한 응답 (Cache) 400 Bad Request All about client error 401 Unauthorized Really means UNAUTHENTICATED 403 Forbidden Really means UNAUTHORIZED 404 Not Found 405 Method Not Allowed 422 Unprocessable Entity Validation Error (406 is also acceptable) 500 Server Error
  • 31. REQUEST & RESPONSE – CONTENT NEGOTIATION Content & Language Negotiation 31 // Request GET /v1/things HTTP/1.1 Accept: application/json Accept-Language: ko-KR;q=0.8,en-US;q=0.6,en;q=0.4 // Response HTTP/1.1 200 OK Content-Type: application/json
  • 32. REQUEST & RESPONSE - TRAMSFORMATION Transformer to decouple a PRESENTATION layer from the DOMAIN layer 32
  • 33. REQUEST & RESPONSE - TRANSFORMATION Transformer to decouple PRESENTATION layer from DOMAIN layer 33 <?php class ThingsController extends Controller { public function index() { return array_map(function($thing) { return [ 'id' => (int) $thing->id, 'meta' => ['version' => 1], '...' => '...' ]; }, AppThing::all()); } }
  • 34. REQUEST & RESPONSE - SERIALIZATION Serialize the response data to format it properly 34
  • 35. REQUEST & RESPONSE – SERIALIZATION league/fractal natively supports DataArraySerializer, ArraySerializer, JsonApiSerializer 35 // DataArraySerializer {"data":{"foo":"bar"}} // instance {“data":[{"foo":"bar"}]} // collection // ArraySerializer {"foo":"bar"} // instance {"data":{"foo":"bar"}} // collection // JsonApiSerializer {"data":{"type":"books","id":1,"attributes":{"foo":"bar"}}} // instance {"data":[{"type":"books","id":1,"attributes":{"foo":"bar"}}]} // collection http://fractal.thephpleague.com/serializers/
  • 36. REQUEST & RESPONSE – ERROR RESPONSE BODY Error response 는 최대한 Descriptive 하게. DEBUG 모드에서는 Stack Trace등 디버그 정보도 출력하면 편리함. 36 // Response { "error": { "code": 400, "message": "Deliberate Error", "dictionary": "http: //developers.fakehost/v1/errors/400" }, "debug": { "line": 42, "file": "..." } }
  • 37. REQUEST & RESPONSE - HATEOAS Hypermedia As The Engine Of Application State. In case of normal HTML response, client can navigate sub resources through set of links. 37
  • 38. REQUEST & RESPONSE - HATEOAS API 사용자가 길을 잃지 않도록 Sub Resource(Nested)에 대한 링크를 포함. 38 // Response { "data": [ { "id": 100, "title": "Quia sunt culpa numquam blanditiis...", "link": { "rel": "self", "href": "http://fakehost/v1/things/100" } }, {"...": "..."} ] }
  • 39. appkr/fractal 39 league/fractal Wrapper for Laravel5/Lumen5 Focuses on RESPONSE(=View layer) of the API response
  • 40. HOW TO INSTALL // composer.json "require": { "appkr/fractal": "0.5.*", "league/fractal": "@dev", } $ composer update // config/app.php 'providers'=> [ AppkrFractalApiServiceProvider::class, ] 40
  • 41. HOW TO USE 41 // app/Http/routes.php Route::resource( 'things', ThingsController::class, ['except' => ['create', 'edit']] ); // app/Http/Controllers/ThingsController class ThingsController extends Controller { public function index(AppkrFractalHttpResponse $response) { return $response->setMeta(['version' => 1])->withPagination( AppThing::latest()->paginate(25), new AppTransformersThingTransformer ); } }
  • 42. HOW TO USE 42 // Response { "data": [ { "id": 1, "title": "Quia sunt culpa numquam blanditiis.", "created_at": "2015-09-19T08:07:55+0000", "link": { "rel": "self", "href": "http://localhost:8000/v1/things/1?include=author" }, "author": "landen08" }, { "...": "..." } ], "meta": { "version": 1, "pagination": { "total": 106, "count": 25, "per_page": 25, "current_page": 1, "total_pages": 5, "links": { "next": "http://localhost:8000/v1/things/?page=2" } } } }
  • 43. HOW TO ACTIVATE & TEST EXAMPLES Database migrations and seeder, Routes definition, Eloquent Model and corresponding Controller, FormRequest, Transformer, Integration Test 43 // Activate examples at vendor/appkr/fractal/src/ApiServiceProvider.php $this->publishExamples(); // Migrate/seed tables at a console $ php artisan migrate --path="vendor/appkr/fractal/database/migrations" $ php artisan db:seed —class="AppkrFractalExampleDatabaseSeeder" // Boot up a local server $ php artisan serve // Request to the endpoint using CURL or POSTMAN GET http://localhost:8000/v1/things GET http://localhost:8000/v1/things/{id} POST http://localhost:8000/v1/things PUT http://localhost:8000/v1/things/{id} // Method overriding required DELETE http://localhost:8000/v1/things/{id} // Method overriding required
  • 44. 떡밥!!! 스스로 찾아 더 공부해 보세요 44
  • 45. AUTO-INCREMENT ID (BAD DESIGN) zackkitzmiller/timy, jenssengers/optimus 45 인증과 권한부여가 없는 식당예약 API를 호출했더니, 내 식당 예약이 /reservations/15로 리턴됨. “덕질” /reservations/14 요청해 보실거죠? 여기까지.. 더하면 잡혀 가요.
  • 46. 구현 참고 http://laravel.io/bin/JxXyW AUTO-INCREMENT ID (BAD DESIGN) // app/Providers/AppServiceProviders.php public function register() { $this->app->singleton(Optimus::class, function () { return new JenssegersOptimus(1118129599, 664904255, 1002004882); }); } // app/BaseModel.php abstract class BaseModel extends Model { public function getIdAttribute($value) { return app(Optimus::class)->encode($value); } public static function find($id, $columns = ['*']) { $transformedId = app(JenssegersOptimusOptimus::class)->decode($id); return static::query()->find($transformedId, $columns); } } // app/SomeModel.php class SomeModel extends BaseModel { } // app/Http/Controllers/SomeController.php public function show($id) { return SomeModel::find($id); } 46
  • 47. AUTHENTICATION laravel/socialite, league/oauth2-server, tymon/jwt-auth 47 Access Control, Throttling, … 등을 위해 필요합니다. 1st/3rd Party Oauth2, JWT 이용 SSL 권장
  • 48. AUTHENTICATION 3rd Party Auth/JWT 구현 참고 appkr/rest // app/Http/Controllers/Api/Auth/SocialController.php protected function handleProviderCallback($provider) { $user = Socialite::with($provider)->user(); return $user = $this->repo->firstOrCreate([ '...', 'email' => $user->getEmail(), 'avatar' => $user->getAvatar() ], $this); } // app/Http/Controllers/Api/Auth/SessionController.php protected function respondLoginSuccess(AuthRequest $request, User $user) { $meta = $this->buildUserMeta($user); return $this->response->setMeta(['token' => JWTAuth::fromUser($user)])->success(); } // app/Http/Controllers/Api/ThingsController.php public function __construct() { $this->middleware('jwt.auth', ['except' => ['index', 'show']]); } // Request POST /v1/things Authorization: Bearer header.payload.signature 48
  • 49. AUTHORIZATION bican/roles, cartalyst/sentinel, graham-campbell/throttle 49 RBAC + Laravel Native API의 공평한 분배를 통한 정의사회 구현 Data가 재산인 시대에 Data API로 돈 벌려면 Throttle은 필수 Object User: teapot Member Admin Guest Roles Read all resource CRUD against my resource Permissions http://bcho.tistory.com/955
  • 50. AUTHORIZATION RBAC, Throttle 구현 참고 appkr/rest // app/Http/Middleware/RoleMiddleware.php public function handle($request, Closure $next, $role) { if (! $request->user()->is($role)) { if ($request->ajax() or $request->is('v1/*')) { throw new Exception('Forbidden', 403); } } return $next($request); } // app/Http/Middleware/ThrottleMiddleware.php public function handle($request, Closure $limit = 10, $time = 60) { if (! $this->throttle->attempt($request, $limit, $time))) { throw new TooManyRequestHttpException($time * 60, 'Rate limit exceeded.'); } return $next($request); } // app/Http/Controllers/Api/ThingsController.php public function __construct() { $this->middleware('role:member', ['except' => ['index', 'show']]); $this->middleware('throttle:10,1'); } 50
  • 51. CORS Reverse Proxy가 최선. 차선은 Access-Control-Allow-Origin HTTP Header 조작: Barryvdh/laravel-cors, asm89/stack-cors. 폭탄 넘기기: jsonp 51 API 서버로 Ajax 요청을 하는 JavaScript를 실행하는 도메 인과, API 서버의 도메인이 다르면 에러납니다. Same Origin Policy Scheme, Port도 같아야 해요!!! Browser http://fakesvc.com http://api.fakehost.com Load JS API Call via Ajax (X) http://bcho.tistory.com/955
  • 52. CACHING Application(Domain) Level의 Cache Cache에 적재해 놓고, Create, Update, Delete 액션이 발생하면 Cache 삭제 52 // app/Http/Controllers/v1/ThingsController.php class ThingsController extends Controller { public function index() { Cache::get('things', function () { return AppThings::all(); }); } public function store() { ... event(new AppEventsClearCache('things')); } }
  • 53. CACHING Application(Domain) Level의 Cache Cache에 적재해 놓고, Create, Update, Delete 액션이 발생하면 Cache 삭제 53 // app/Events/ClearCache.php public function __construct($tags) { $this->tags = $tags; } // app/Listeners/CacheListener.php public function handle(ClearCache $event) { if (!is_array($event->tags)) { return $this->cache->tags($event->tags)->flush(); } foreach ($event->tags as $tag) { $this->cache->tags($tag)->flush(); } return; }
  • 54. CACHING ETAG/If-None-Match 또는 Last-Modified/If-Modified-Since 를 이용한 Cache. API 소비자는 Web Browser만 있는게 아니다. 54 Client Server GET /v1/things https://en.wikipedia.org/wiki/HTTP_ETag 200 OK ETag: 686897696a7c876b7e Cache Storage (key: 6868..) Later …. GET /v1/things If-None-Match: 686897696a7c876b7e 304 Not Modified
  • 55. API MODELING LANGUAGE/SERVICE http://raml.org/, https://apiblueprint.org/, https://apiary.io/ 55 REST API Modeling Language (혼자 개발하기에) 저는 안 써 봤습니다;;; (팀웍하신다면) 한번 써 보세요.
  • 56. 56 • http://www.slideshare.net/landlessness/teach-a-dog-to-rest, https://www.youtube.com/watch?v=QpAhXa12xvU • https://laracasts.com/series/incremental-api-development FURTHER READINGS RESTful API에 대해 더 공부하고 싶거나, Laravel에서 API 구현 방안에 대해 더 공부하고 싶으시다면..
  • 57. Summary 57 1. REST 원칙을 이해한다. Method, Resource, Message(Response) 2. 남의 것을 읽을 수 있다. API Document를 모두 읽을 필요는 없다. 3. 내 것을 만들 수 있다. 직접, appkr/fractal, dingo/api 이용.