Open API 와Ruby on Rails에 대한 이야기푸딩 Lab | 조범석                1
부탁의 말씀이번 세션은 간접 광고와 개드립,무리수를 포함하고 있습니다재미 없으시더라도 많은 호응 부탁드립니다                   2
오늘의 주제  +         =실화를 바탕으로 재구성 하였습니다                          3
오늘의 주제  +         =실화를 바탕으로 재구성 하였습니다                          3
Pudding.to 소개푸딩 시리즈의 막내사진 기반 사회 관계망 서비스                               4
Pudding.to 소개푸딩 시리즈의 막내사진 기반 사회 관계망 서비스                               4
서비스는 계속 변합니다사회 관계망 서비스만의 얘기는 아니지요                           5
서비스는 계속 변합니다               5
서비스는 계속 변합니다               5
Pudding LabServer API 개발이주 업무Open API의 필요성                   6
Pudding.to 구조                                 Database (RDS)                            Replication                    Dat...
Pudding.to 구조                                 Database (RDS)                            Replication                    Dat...
왜 따로 개발 했나?코드가 복잡 해 져요!                       8
왜 따로 개발 했나?서비스API vs. OpenAPI                           8
왜 따로 개발 했나?서비스 정책 및 인증                       8
별도의 Framework가 필요해?기존 Application 재활용 불가부족한 개발 일정장기적인 서비스 구조 개선을 위한 준비                                9
Framework 선택Pros  개인적인 선호  고성능, 빠른 발전Cons  개발자들의 Javascript에 대한 불안감                                    10
Framework 선택Pros  JVM 상에서 동작  고성능Cons  새로운 언어 학습에 대한 부담감                                     10
Framework 선택Pros  웹 프레임워크의 유행 선도자  높은 생산성, 개발 경험이 있음Cons  낮은 VM 성능                                     10
11
?    11
좋은 API의 특징쉽게 배울 수 있어야 한다                              12
좋은 API의 특징문서 없이도 사용이 가능해야 한다                            12
좋은 API의 특징실수의 여지가 적어야 한다                              12
좋은 API의 특징확장 하기 쉬워야 한다                            12
좋은 API의 특징사용자가 필요로 하는 것을 제공 해야 한다                            12
좋은 API의 특징요구사항에 맞게 동작해야 한다                            12
MVC - ControllerURL 설계VersioningCORS                                13
Controller #1 - URL 설계 및 RESTfulURL 설계는 Open API의 기초 공사  제공 하는 Resource 를 정의  Meaningful URL 혹은 Pretty URL                ...
Controller #1 - URL 설계 및 RESTful    RESTful 한 API         가장 일반적인 URL 설계 규칙HTTP Method             URL                Func...
Controller #1 - URL 설계 및 RESTful진정한 REST 구조?  단일 Resource 만 제공 할 것인가, 여러 Resource  를 동시에 제공 할 것인가  우선 엄격한 REST API 개발 하고 성...
Controller #2 - Versioning  OpenAPI 변경 주기에 대한 확장성 확보          DeprecatedV1V2                       ObsoleteTime           ...
Controller #2 - Versioning어느 수준에서 분리 하느냐의 문제 Application 내의 Routing 처리 Domain 분리 및 Application 분리                         ...
Controller #3 - CORSCross-Origin Resource Sharing Ajax 를 통한 JS 코드 실행은 같은 도메인에서만 가능 웹 브라우저 기반의 Mesh-up App 에서는 문제 발생       ...
Controller #3 - CORS api_controller.rbmodule Api  class ApiController < ApplicationController    before_filter :cors_prefl...
Controller #3 - CORS/openapi.pudding.to    /app/controllers        /api             /api_controller.rb             /v1    ...
MVC -ModelActiveRecord 소개ActiveSupport::Concern 을 통한 확장Composite KeysDB Replication                                   17
Model #1 - ActiveRecordORM (Object Relation Mapper)  DB 의 각 Table 이 Model Class에 매핑  Foreign Key 로 모델 객체들간의 관계를 정의        ...
Model #1 - ActiveRecord      Table : PHOTO                 id                   integer         PK, Auto inc.             ...
Model #2 - ActiveRecord AssociationUser                   Photo       1           n                                       ...
Model #2 - ActiveRecord Association photo.rbclass Photo < ActiveRecord::Base  belongs_to :user  def link_to_user_email    ...
Model #3 - 문제의 원인이게 다 노무ㅎ...아니 전임자 탓이다!                                20
Model #4 - Legacy ProblemDB 설계 시 컬럼명이 대문자로 구성   Ruby 코딩 관례와 충돌   컬럼명이 다른 용도로 사용 되거나 혼동의 여지가 있   다면 변경이 필요“#{photo.MESSAGE}...
Model #5 - ActiveSupport::Concern /extra/active_model/column_naming.rbmodule ActiveModel  module ColumnNaming    extend Ac...
Model #5 - ActiveSupport::Concern photo.rbclass Photo < ActiveRecord::Base  include ActiveModel::ColumnNaming    rename_co...
Model #6 - Composite KeyActiveRecord 는 합성키를 지원하지 않음  CompositePrimaryKeys Gem  기본적인 RoR 개발 방식을 따르면 벌어지지 않을 일              ...
Model #7 - DB Replication                                 Database (RDS)                            Replication           ...
Model #7 - DB Replication                                 Database (RDS)                            Replication           ...
Model #7 - DB ReplicationGems Seamless Database Pool    설정이 용이 Octopus    가장 제공 기능이 많음    테스트 당시 Rails 3.2.x 호환성에 문제 Multi...
Model #7 - DB Replication config/database.ymlpudding_db:  adapter: seamless_database_pool  pool_adapter: mysql2  encoding:...
MVC - ViewRABL대안 JSONLibrary Gems                            25
View #1 - RABLRABL : API view 를 위한 템플릿 엔진  다양한 포맷(JSON, XML, Message  Pack, BSON, Plist) 지원  템플릿 내에서 Ruby 코드를 사용 가능       ...
View #1 - RABL photos_controller.rbmodule Api  module V1    class Api::V1::PhotosController < ApiController      def by_us...
View #1 - RABL by_user.rablobject falsenode :result do  trueendnode :data do  attributes :total_count => @total_count.to_i...
View #1 - RABL    /v1/users/12345/photos.json{    result: true,    data: {      total_count: 9,      count: 10,      offse...
View #2 - JSONRoR 기본 JSON 라이브러리JSON Library Gems Yaji (https://github.com/brianmario/yajl- ruby) Oj (https://github.com/oh...
정리하며관심의 분리  스파게티 코드는 이제 그만좋은 기술, 신기술도 꿸 줄 알아야 보배  독고다이는 패가망신의 지름길  팀의 절반 이상이 해당 기술에 익숙한가고난의 길을 먼저 걸은 선구자를 찾아라  오픈소스의 가장 큰 ...
참고 자료1. How to design a good API and why it matters.    http://lcsd05.cs.tamu.edu/slides/keynote.pdf2. Cross-Origin Resour...
감사합니다. 개발실 / 푸딩 Lab PD / 조범석leopard2a6@kthcorp.com     @ACodeFarmer                         30
Upcoming SlideShare
Loading in …5
×

[H3 2012] Open API 와 Ruby on Rails 에 대한 이야기

3,363 views

Published on

H3 2012 발표자료
Open API 와 Ruby on Rails 에 대한 이야기
-KTH 조범석

Published in: Technology
0 Comments
10 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,363
On SlideShare
0
From Embeds
0
Number of Embeds
466
Actions
Shares
0
Downloads
47
Comments
0
Likes
10
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • [H3 2012] Open API 와 Ruby on Rails 에 대한 이야기

    1. 1. Open API 와Ruby on Rails에 대한 이야기푸딩 Lab | 조범석 1
    2. 2. 부탁의 말씀이번 세션은 간접 광고와 개드립,무리수를 포함하고 있습니다재미 없으시더라도 많은 호응 부탁드립니다 2
    3. 3. 오늘의 주제 + =실화를 바탕으로 재구성 하였습니다 3
    4. 4. 오늘의 주제 + =실화를 바탕으로 재구성 하였습니다 3
    5. 5. Pudding.to 소개푸딩 시리즈의 막내사진 기반 사회 관계망 서비스 4
    6. 6. Pudding.to 소개푸딩 시리즈의 막내사진 기반 사회 관계망 서비스 4
    7. 7. 서비스는 계속 변합니다사회 관계망 서비스만의 얘기는 아니지요 5
    8. 8. 서비스는 계속 변합니다 5
    9. 9. 서비스는 계속 변합니다 5
    10. 10. Pudding LabServer API 개발이주 업무Open API의 필요성 6
    11. 11. Pudding.to 구조 Database (RDS) Replication Data Read Cache Data WriteCDN (Cloudfront) Storage (S3) API (EC2) Image Upload Image Download API Call Client (iOS/Android) 7
    12. 12. Pudding.to 구조 Database (RDS) Replication Data Read Cache Data WriteCDN (Cloudfront) Storage (S3) API (EC2) Image Upload Image Download ? API Call OpenAPI (EC2) Client (iOS/Android) 7
    13. 13. 왜 따로 개발 했나?코드가 복잡 해 져요! 8
    14. 14. 왜 따로 개발 했나?서비스API vs. OpenAPI 8
    15. 15. 왜 따로 개발 했나?서비스 정책 및 인증 8
    16. 16. 별도의 Framework가 필요해?기존 Application 재활용 불가부족한 개발 일정장기적인 서비스 구조 개선을 위한 준비 9
    17. 17. Framework 선택Pros 개인적인 선호 고성능, 빠른 발전Cons 개발자들의 Javascript에 대한 불안감 10
    18. 18. Framework 선택Pros JVM 상에서 동작 고성능Cons 새로운 언어 학습에 대한 부담감 10
    19. 19. Framework 선택Pros 웹 프레임워크의 유행 선도자 높은 생산성, 개발 경험이 있음Cons 낮은 VM 성능 10
    20. 20. 11
    21. 21. ? 11
    22. 22. 좋은 API의 특징쉽게 배울 수 있어야 한다 12
    23. 23. 좋은 API의 특징문서 없이도 사용이 가능해야 한다 12
    24. 24. 좋은 API의 특징실수의 여지가 적어야 한다 12
    25. 25. 좋은 API의 특징확장 하기 쉬워야 한다 12
    26. 26. 좋은 API의 특징사용자가 필요로 하는 것을 제공 해야 한다 12
    27. 27. 좋은 API의 특징요구사항에 맞게 동작해야 한다 12
    28. 28. MVC - ControllerURL 설계VersioningCORS 13
    29. 29. Controller #1 - URL 설계 및 RESTfulURL 설계는 Open API의 기초 공사 제공 하는 Resource 를 정의 Meaningful URL 혹은 Pretty URL 14
    30. 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. 31. Controller #1 - URL 설계 및 RESTful진정한 REST 구조? 단일 Resource 만 제공 할 것인가, 여러 Resource 를 동시에 제공 할 것인가 우선 엄격한 REST API 개발 하고 성능이 필요한 부분 에 대해서 타협 14
    32. 32. Controller #2 - Versioning OpenAPI 변경 주기에 대한 확장성 확보 DeprecatedV1V2 ObsoleteTime 15
    33. 33. Controller #2 - Versioning어느 수준에서 분리 하느냐의 문제 Application 내의 Routing 처리 Domain 분리 및 Application 분리 15
    34. 34. Controller #3 - CORSCross-Origin Resource Sharing Ajax 를 통한 JS 코드 실행은 같은 도메인에서만 가능 웹 브라우저 기반의 Mesh-up App 에서는 문제 발생 16
    35. 35. Controller #3 - CORS api_controller.rbmodule 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  endend 16
    36. 36. Controller #3 - CORS/openapi.pudding.to /app/controllers /api /api_controller.rb /v1 /photos_controller.rb photos_controller.rbmodule Api  module V1    class Api::V1::PhotosController < ApiController end  endend 16
    37. 37. MVC -ModelActiveRecord 소개ActiveSupport::Concern 을 통한 확장Composite KeysDB Replication 17
    38. 38. Model #1 - ActiveRecordORM (Object Relation Mapper) DB 의 각 Table 이 Model Class에 매핑 Foreign Key 로 모델 객체들간의 관계를 정의 18
    39. 39. Model #1 - ActiveRecord Table : PHOTO id integer PK, Auto inc. message text - user_id integer - photo.rbclass Photo < ActiveRecord::Baseend photo_controller.rbmodule Api  module V1    class Api::V1::PhotosController < ApiController      def message_and_user_login        “#{self.message} - #{self.user.loginname} “      end end endend 18
    40. 40. Model #2 - ActiveRecord AssociationUser Photo 1 n 19
    41. 41. Model #2 - ActiveRecord Association photo.rbclass Photo < ActiveRecord::Base belongs_to :user def link_to_user_email    “<a href=‘mailto:#{self.user.email}’>#{self.user.loginname}</a>”  endend user.rbclass User < ActiveRecord::Base has_many :photos def get_all_photos    self.photos  endend 19
    42. 42. Model #3 - 문제의 원인이게 다 노무ㅎ...아니 전임자 탓이다! 20
    43. 43. Model #4 - Legacy ProblemDB 설계 시 컬럼명이 대문자로 구성 Ruby 코딩 관례와 충돌 컬럼명이 다른 용도로 사용 되거나 혼동의 여지가 있 다면 변경이 필요“#{photo.MESSAGE}”...photo.user.USER_NAME 21
    44. 44. Model #5 - ActiveSupport::Concern /extra/active_model/column_naming.rbmodule 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  endend 22
    45. 45. Model #5 - ActiveSupport::Concern photo.rbclass 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}” endend 22
    46. 46. Model #6 - Composite KeyActiveRecord 는 합성키를 지원하지 않음 CompositePrimaryKeys Gem 기본적인 RoR 개발 방식을 따르면 벌어지지 않을 일 23
    47. 47. Model #7 - DB Replication Database (RDS) Replication Data Read Cache Data WriteCDN (Cloudfront) Storage (S3) API (EC2) Image Upload Image Download API Call Client (iOS/Android)
    48. 48. Model #7 - DB Replication Database (RDS) Replication Data Read Cache Data WriteCDN (Cloudfront) Storage (S3) API (EC2) Image Upload Image Download API Call Client (iOS/Android)
    49. 49. Model #7 - DB ReplicationGems Seamless Database Pool 설정이 용이 Octopus 가장 제공 기능이 많음 테스트 당시 Rails 3.2.x 호환성에 문제 Multi Db 설정방식이 복잡
    50. 50. Model #7 - DB Replication config/database.ymlpudding_db:  adapter: seamless_database_pool  pool_adapter: mysql2  encoding: utf8  master:    host: master_db.pudding.to    pool_weight: 0  read_pool:    - host: slave01_db.pudding.to      pool_weight: 2    - host: slave02_db.pudding.to      pool_weight: 1
    51. 51. MVC - ViewRABL대안 JSONLibrary Gems 25
    52. 52. View #1 - RABLRABL : API view 를 위한 템플릿 엔진 다양한 포맷(JSON, XML, Message Pack, BSON, Plist) 지원 템플릿 내에서 Ruby 코드를 사용 가능 26
    53. 53. View #1 - RABL photos_controller.rbmodule Api  module V1    class Api::V1::PhotosController < ApiController def by_user        @count = params[:count].nil? ? 10 : params[:count]        @offset = params[:offset].nil? ? 0 : params[:offset]        @total_count = Photo.count_by_user params[:user_id]        @photos = Photo.by_user params[:user_id], @count, @offset      end  end  endend 26
    54. 54. View #1 - RABL by_user.rablobject falsenode :result do  trueendnode :data do  attributes :total_count => @total_count.to_i, :count => @count.to_i, :offset =>@offset.to_i, :photos => partial("api/v1/photos/photo_simple", :object => @photos)end photo_simple.rablobject @photoattributes :id, :contents, :photo_url, :medium_photo_url, :small_photo_url,:likes_count, :comments_count, :created_timenode :user do |p|  partial("api/v1/users/user_simple", :object => p.user)endnode :music do |p|  attributes :artist => p.music_artist.nil? ? "" : p.music_artist, :title =>p.music_title.nil? ? "" : p.music_titleend 26
    55. 55. View #1 - RABL /v1/users/12345/photos.json{ result: true, data: { total_count: 9, count: 10, offset: 0, photos: [ { id: 3996200, contents: "#api 로고", photo_url: "http://img.pudding.to/....781191558632.jpg", .... likes_count: 3, comments_count: 2, created_time: 1343266129, user: { id: 12345, nickname: "api_puddingto", ... } }, ... ] }} 26
    56. 56. View #2 - JSONRoR 기본 JSON 라이브러리JSON Library Gems Yaji (https://github.com/brianmario/yajl- ruby) Oj (https://github.com/ohler55/oj) 27
    57. 57. 정리하며관심의 분리 스파게티 코드는 이제 그만좋은 기술, 신기술도 꿸 줄 알아야 보배 독고다이는 패가망신의 지름길 팀의 절반 이상이 해당 기술에 익숙한가고난의 길을 먼저 걸은 선구자를 찾아라 오픈소스의 가장 큰 장점영어 실력만이 살 길이다 28
    58. 58. 참고 자료1. How to design a good API and why it matters. http://lcsd05.cs.tamu.edu/slides/keynote.pdf2. Cross-Origin Resource Sharing for JSON and Rails http://www.tsheffler.com/blog/?p=4283. 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
    59. 59. 감사합니다. 개발실 / 푸딩 Lab PD / 조범석leopard2a6@kthcorp.com @ACodeFarmer 30

    ×