29. Controller #1 - URL 설계 및 RESTful
URL 설계는 Open API의 기초 공사
제공 하는 Resource 를 정의
Meaningful URL 혹은 Pretty URL
14
30. Controller #1 - URL 설계 및 RESTful
RESTful 한 API
가장 일반적인 URL 설계 규칙
HTTP Method URL Function
GET http://pud.to/photos list
GET http://pud.to/photos/123 show
POST http://pud.to/photos create
POST, PUT http://pud.to/photos/123 update
DELETE http://pud.to/photos/123 delete
14
31. Controller #1 - URL 설계 및 RESTful
진정한 REST 구조?
단일 Resource 만 제공 할 것인가, 여러 Resource
를 동시에 제공 할 것인가
우선 엄격한 REST API 개발 하고 성능이 필요한 부분
에 대해서 타협
14
32. Controller #2 - Versioning
OpenAPI 변경 주기에 대한 확장성 확보
Deprecated
V1
V2
Obsolete
Time
15
33. Controller #2 - Versioning
어느 수준에서 분리 하느냐의 문제
Application 내의 Routing 처리
Domain 분리 및 Application 분리
15
34. Controller #3 - CORS
Cross-Origin Resource Sharing
Ajax 를 통한 JS 코드 실행은 같은 도메인에서만 가능
웹 브라우저 기반의 Mesh-up App 에서는 문제 발생
16
35. Controller #3 - CORS
api_controller.rb
module Api
class ApiController < ApplicationController
before_filter :cors_preflight_check
after_filter :cors_set_access_control_header
def cors_preflight_check
if request.method == :options
headers[‘Access-Control-Allow-Origin’] = “*”
headers[‘Access-Control-Allow-Methods’] = “POST, GET, OPTIONS”
headers[‘Access-Control-Allow-Headers’] = “X-Requested-With, X-Prototype-
Version”
headers[‘Access-Control-Max-Ages’] = “1728000”
render :text => “”, :content_type => “text/plain”
end
end
def cors_set_access_control_header
headers[‘Access-Control-Allow-Origin’] = “*”
headers[‘Access-Control-Allow-Methods’] = “POST, GET, OPTIONS”
headers[‘Access-Control-Max-Ages’] = “1728000”
end
end
end
16
36. Controller #3 - CORS
/openapi.pudding.to
/app/controllers
/api
/api_controller.rb
/v1
/photos_controller.rb
photos_controller.rb
module Api
module V1
class Api::V1::PhotosController < ApiController
end
end
end
16
38. Model #1 - ActiveRecord
ORM (Object Relation Mapper)
DB 의 각 Table 이 Model Class에 매핑
Foreign Key 로 모델 객체들간의 관계를 정의
18
39. Model #1 - ActiveRecord
Table : PHOTO
id integer PK, Auto inc.
message text -
user_id integer -
photo.rb
class Photo < ActiveRecord::Base
end
photo_controller.rb
module Api
module V1
class Api::V1::PhotosController < ApiController
def message_and_user_login
“#{self.message} - #{self.user.loginname} “
end
end
end
end
18
40. Model #2 - ActiveRecord Association
User Photo
1 n
19
41. Model #2 - ActiveRecord Association
photo.rb
class Photo < ActiveRecord::Base
belongs_to :user
def link_to_user_email
“<a href=‘mailto:#{self.user.email}’>#{self.user.loginname}</a>”
end
end
user.rb
class User < ActiveRecord::Base
has_many :photos
def get_all_photos
self.photos
end
end
19
43. Model #4 - Legacy Problem
DB 설계 시 컬럼명이 대문자로 구성
Ruby 코딩 관례와 충돌
컬럼명이 다른 용도로 사용 되거나 혼동의 여지가 있
다면 변경이 필요
“#{photo.MESSAGE}”
...
photo.user.USER_NAME
21
44. Model #5 - ActiveSupport::Concern
/extra/active_model/column_naming.rb
module ActiveModel
module ColumnNaming
extend ActiveSupport::Concern
def serializable_hash(options = nil)
hash = super(options)
self.class.columns_map.each do |legacy, renamed|
hash[renamed] = hash.delete(legacy)
end
hash
end
module ClassMethods
def columns_map
@columns_map
end
def rename_columns(map)
@columns_map = map.invert
columns_map.each { |key, value| alias_attribute value.to_sym, key.to_sym }
end
end
end
end
22
45. Model #5 - ActiveSupport::Concern
photo.rb
class Photo < ActiveRecord::Base
include ActiveModel::ColumnNaming
rename_columns({
id: "PHOTOID",
user_id: "UID",
contents: "CONTENTS",
...
created_time: "REG_DATE",
status: "STATUS"
})
def some_method
“#{self.content} - #{self.user.name}”
end
end
22
46. Model #6 - Composite Key
ActiveRecord 는 합성키를 지원하지 않음
CompositePrimaryKeys Gem
기본적인 RoR 개발 방식을 따르면 벌어지지 않을 일
23
47. Model #7 - DB Replication
Database (RDS)
Replication Data Read
Cache
Data Write
CDN (Cloudfront) Storage (S3) API (EC2)
Image Upload
Image Download API Call
Client (iOS/Android)
48. Model #7 - DB Replication
Database (RDS)
Replication Data Read
Cache
Data Write
CDN (Cloudfront) Storage (S3) API (EC2)
Image Upload
Image Download API Call
Client (iOS/Android)
49. Model #7 - DB Replication
Gems
Seamless Database Pool
설정이 용이
Octopus
가장 제공 기능이 많음
테스트 당시 Rails 3.2.x 호환성에 문제
Multi Db
설정방식이 복잡
57. 정리하며
관심의 분리
스파게티 코드는 이제 그만
좋은 기술, 신기술도 꿸 줄 알아야 보배
독고다이는 패가망신의 지름길
팀의 절반 이상이 해당 기술에 익숙한가
고난의 길을 먼저 걸은 선구자를 찾아라
오픈소스의 가장 큰 장점
영어 실력만이 살 길이다
28
58. 참고 자료
1. How to design a good API and why it matters.
http://lcsd05.cs.tamu.edu/slides/keynote.pdf
2. Cross-Origin Resource Sharing for JSON and
Rails
http://www.tsheffler.com/blog/?p=428
3. Concerning yourself with
ActiveSupport::Concern
http://www.fakingfantastic.com/2010/09/20/concerning-yourself-
with-active-support-concern/
4. Lightning JSON in Rails
http://brainspec.com/blog/2012/09/28/lightning-json-in-rails/
29