Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How to use OpenAPI3 for API developer (RubyKaigi 2019)

ota42y
April 18, 2019

How to use OpenAPI3 for API developer (RubyKaigi 2019)

ota42y

April 18, 2019
Tweet

More Decks by ota42y

Other Decks in Technology

Transcript

  1. How to use OpenAPI 3
    for API developer
    RubyKaigi 2019
    ota42y (FiNC Technologies)

    View Slide

  2. Today’s Topic
    • Introduce OpenAPI 3 and explain why it is necessary
    • The OpenAPI 3 specification
    • How to use OpenAPI 3
    • Request / response validation
    • A story about how to implement OpenAPI 3 feature
    • Other OpenAPI 3 tools

    View Slide

  3. about me
    • @ota42y (github/twitter)
    • Server side engineer at FiNC Technologies
    • I maintain request/response validation gem using OpenAPI 3

    View Slide

  4. 2F

    View Slide

  5. Introduce OpenAPI 3 and
    explain why it is necessary

    View Slide

  6. OpenAPI 3
    • programming language-agnostic definition for REST API
    • OpenAPI 3 means OpenAPI specification version 3
    • previously known as Swagger so Swagger 2 == OpenAPI 2
    https://www.openapis.org/

    View Slide

  7. Definition of OpenAPI 3
    • It’s machine-readable API definition rule
    • Definition of OpenAPI 3 is described in YAML or JSON
    formats
    • We can use it as interactive document generation, validation,
    mock-server, client library, etc…(I’ll talk about it later)

    View Slide

  8. Sometimes the machine-readable API
    schema is important
    • When we create many APIs
    • When we want to do schema-first development
    • etc…

    View Slide

  9. When we create many APIs
    • Backend API server for iOS/Android/Web(SPA)
    • We have many JSON APIs

    (We use microservices architecture so 1000 over endpoints )
    • API schema is very important for interface documentation

    View Slide

  10. Schema first development
    • Schema first development
    • Define API schema
    • Client-side and server-side implement according it
    • Integration test
    • Without Schema first development, 

    we can’t start client-side implement until server side implement finished
    Reference:
    RubyKaigi 2017 API Development in 2017 https://www.youtube.com/watch?v=a28jJ62ZfZM
    Rails Developers Meetup 2019: 

    https://speakerdeck.com/aeroastro/rails-meets-protocol-buffers-for-schema-first-development

    View Slide

  11. Definition and implementation
    must be always same
    • If there are difference we can’t trust API schema
    • Even if we passed unit test, we gets bug on integration test
    • But it’s difficult to avoid making mistakes

    View Slide

  12. The machine-readable API schema is
    important
    • We can find mistakes API automatically using the schema
    • So always the schema and definition is matched
    • We can use schema to generate human-readable docs, client
    library, etc…

    View Slide

  13. OpenAPI 3

    View Slide

  14. OpenAPI is one of the definition
    method
    • JSON Hyper-Schema
    • It defines hypermedia specifications, and it can also be used to
    define REST API too
    • GraphQL
    • Query language and runtime
    • The response can be specified in the query sent from the client

    View Slide

  15. OpenAPI is one of the definition
    method
    • gRPC
    • RPC framework using protocol buffers and HTTP/2
    • It generates code from interface definition and do almost all
    communication processing

    View Slide

  16. OpenAPI extends REST API
    • OpenAPI is just a YAML/JSON rule
    • Actual processing is just REST API
    • OpenAPI 3 takes full advantage of existing RESTful frameworks
    and insights
    • Since REST is a web best practice at the time, various mechanisms
    such as HTTP cache, monitoring system can also be used

    View Slide

  17. The OpenAPI 3 specification

    View Slide

  18. Example API
    get "/apps" do
    content_type :json
    # page should be Integer
    page = params["page"]
    [page, (page*10)].map(&:to_s).to_json
    end

    View Slide

  19. get "/apps" do
    content_type :json
    # page should be Integer
    page = params["page"]
    [page, (page*10)].map(&:to_s).to_json
    end
    • GET /apps returns application/json
    Example API

    View Slide

  20. get "/apps" do
    content_type :json
    # page should be Integer
    page = params["page"].to_i
    [page, (page*10)].map(&:to_s).to_json
    end
    • GET /apps returns application/json
    • This API requires `page` parameter and must be Integer
    Example API

    View Slide

  21. get "/apps" do
    content_type :json
    # page should be Integer
    page = params["page"].to_i
    [page, (page*10)].map(&:to_s).to_json
    end
    • GET /apps returns application/json
    • This API requires `page` parameter and must be Integer
    • Succeed response includes string array
    Example API

    View Slide

  22. Example API to OpenAPI 3 definition
    openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string

    View Slide

  23. Example API to OpenAPI 3 definition
    • GET /apps
    openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string

    View Slide

  24. Example API to OpenAPI 3 definition
    • GET /apps returns application/json
    openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string

    View Slide

  25. Example API to OpenAPI 3 definition
    • GET /apps returns application/json
    • `page` parameter required and it’s integer
    openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string

    View Slide

  26. Example API to OpenAPI 3 definition
    • GET /apps returns application/json
    • `page` parameter required and it’s integer
    • Succeed response includes string array
    openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string

    View Slide

  27. Example API to OpenAPI 3 definition
    • GET /apps returns application/json
    • `page` parameter required and it’s integer
    • Succeed response includes string array
    openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string

    View Slide

  28. OpenAPI 3 structure
    JOGP
    QBUIT
    TFSWFST
    DPNQPOFOUT
    TFDVSJUZ
    UBHT
    FYUFSOBM%PDT
    required

    View Slide

  29. OpenAPI 3 structure
    JOGP
    QBUIT
    TFSWFST
    DPNQPOFOUT
    TFDVSJUZ
    UBHT
    FYUFSOBM%PDT
    required
    Metadata for this definition
    API definitions
    Target server setting
    Schema objects
    Security settings
    Tags
    External document url

    View Slide

  30. OpenAPI 3 structure
    JOGP
    QBUIT
    TFSWFST
    DPNQPOFOUT
    TFDVSJUZ
    UBHT
    FYUFSOBM%PDT
    required
    Metadata for this definition
    API definitions
    Target server setting
    Schema objects
    Security settings
    Tags
    External document url

    View Slide

  31. openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string
    Paths Object
    • API definitions are written in this section
    • There is path string key and 

    Path Item Object
    • We can write definition in Path Item Object
    Path string
    Path Item Object

    View Slide

  32. openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string
    Path Item Object
    • Define request/response parameter 

    per HTTP method
    Path Item Object

    View Slide

  33. Path Item Object
    • Define request/response parameter 

    per HTTP method
    • We can define request parameter
    openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string

    View Slide

  34. Path Item Object
    • Define request/response parameter 

    per HTTP method
    • We can define request parameter and 

    response parameter schema
    openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string

    View Slide

  35. OpenAPI 3 structure
    JOGP
    QBUIT
    TFSWFST
    DPNQPOFOUT
    TFDVSJUZ
    UBHT
    FYUFSOBM%PDT
    required
    Metadata for this definition
    API definitions
    Target server setting
    Schema objects
    Security settings
    Tags
    External document url

    View Slide

  36. Security Scheme Object
    • We can define security schema for all API or specific API

    View Slide

  37. Security Scheme Object
    • We can define security schema for all API or specific API
    • We can use HTTP authentication
    type: http
    scheme: basic
    type: http
    scheme: bearer
    bearerFormat: JWT
    JWT basic

    View Slide

  38. Security Scheme Object
    • We can define security schema for all API or specific API
    • We can use HTTP authentication, API key (like header, query)
    type: http
    scheme: basic
    type: apiKey
    name: api_key
    in: header
    type: http
    scheme: bearer
    bearerFormat: JWT
    JWT API key
    basic

    View Slide

  39. Security Scheme Object
    • We can define security schema for all API or specific API
    • We can use HTTP authentication, API key (like header, query), 

    OAuth2, OpenID Connect
    type: http
    scheme: basic
    type: apiKey
    name: api_key
    in: header
    type: http
    scheme: bearer
    bearerFormat: JWT
    JWT API key
    basic
    type: oauth2
    flows:
    implicit:
    authorizationUrl: https://example.co...
    scopes:
    write:pets: modify pets
    read:pets: read your pets
    OAuth2

    View Slide

  40. OpenAPI 3 structure
    JOGP
    QBUIT
    TFSWFST
    DPNQPOFOUT
    TFDVSJUZ
    UBHT
    FYUFSOBM%PDT
    required
    openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string

    View Slide

  41. How to use OpenAPI 3

    View Slide

  42. OpenAPI is definition
    • It’s just a rule in YAML/JSON file, so it alone does nothing
    • It is effective by combining it with peripheral tools
    • request/response validation, interactive document
    generation, mock-server, client library, etc…

    View Slide

  43. Request / Response validation

    using OpenAPI 3

    View Slide

  44. We need validation
    • We make mistakes when implementing the API

    View Slide

  45. We need validation
    • We make mistakes when implementing the API
    • OpenAPI is programming language-agnostic definition

    View Slide

  46. We need validation
    • We make mistakes when implementing the API
    • OpenAPI is programming language-agnostic definition
    • So we need a tool to check differences between
    implementation and definition

    View Slide

  47. We need validation
    • We make mistakes when implementing the API
    • OpenAPI is programming language-agnostic definition
    • So we need a tool to check differences between
    implementation and definition
    • This will ensure the credibility of the schema

    View Slide

  48. committee gem
    • Request/Response validation gem

    View Slide

  49. committee gem
    • Request/Response validation gem
    • This gem works as Rack middleware and performs validation
    if requested URL is in definition
    3BDL

    "QQMJDBUJPO
    $MJFOU
    "QQMJDBUJPO
    Request validation
    Response validation
    committee

    View Slide

  50. Request validation using committee
    require "sinatra"
    require "committee"
    use Committee::Middleware::RequestValidation, schema_path: 'schema.yaml'
    use Committee::Middleware::ResponseValidation, schema_path: 'schema.yaml'
    get "/apps" do
    content_type :json
    # page should be Integer
    page = params["page"].to_i
    [page, (page*10)].map(&:to_s).to_json
    end

    View Slide

  51. require "sinatra"
    require "committee"
    use Committee::Middleware::RequestValidation, schema_path: 'schema.yaml'
    use Committee::Middleware::ResponseValidation, schema_path: 'schema.yaml'
    get "/apps" do
    content_type :json
    # page should be Integer
    page = params["page"].to_i
    [page, (page*10)].map(&:to_s).to_json
    end
    Request validation using committee
    committee returns error without `page` parameter
    % curl -X GET "http://localhost:4567/apps"
    {"id":"bad_request","message":"required parameters page not exist in #/paths/~1apps/get”}

    View Slide

  52. Request validation using committee
    % curl -X GET "http://localhost:4567/apps"
    {"id":"bad_request","message":"required parameters page not exist in #/paths/~1apps/get”}
    % curl -X GET "http://localhost:4567/apps?page=1"
    ["1","10"]
    When `page` parameter exists, get correct response
    require "sinatra"
    require "committee"
    use Committee::Middleware::RequestValidation, schema_path: 'schema.yaml'
    use Committee::Middleware::ResponseValidation, schema_path: 'schema.yaml'
    get "/apps" do
    content_type :json
    # page should be Integer
    page = params["page"].to_i
    [page, (page*10)].map(&:to_s).to_json
    end

    View Slide

  53. % curl -X GET "http://localhost:4567/apps?page=1"
    ["1","1111111111"]
    require "sinatra"
    require "committee"
    # use Committee::Middleware::RequestValidation, schema_path: 'schema.yaml'
    # use Committee::Middleware::ResponseValidation, schema_path: 'schema.yaml'
    get "/apps" do
    content_type :json
    # page should be Integer
    page = params["page"]
    [page, (page*10)].map(&:to_s).to_json
    end
    Coerce request parameter
    Normally, request parameters don’t have type and are always string

    View Slide

  54. % curl -X GET "http://localhost:4567/apps?page=1"
    ["1","10"]
    Coerce request parameter
    But committee converts class using definition type (optional feature)
    require "sinatra"
    require "committee"
    use Committee::Middleware::RequestValidation, schema_path: 'schema.yaml'
    use Committee::Middleware::ResponseValidation, schema_path: 'schema.yaml'
    get "/apps" do
    content_type :json
    # page should be Integer
    page = params["page"]
    [page, (page*10)].map(&:to_s).to_json
    end

    View Slide

  55. Coerce request body and other convert
    % curl -X POST -H "Content-Type: application/json"
    -d '{"measured_at":"2016-04-01T16:00:00+09:00"}'
    “http://localhost:4567/apps"
    {"class":"DateTime"}
    post:
    requestBody:
    content:
    application/json:
    schema:
    type: object
    properties:
    measured_at:
    type: string
    format: date-time
    responses:
    '201':
    description: no content
    content:
    'application/json':
    schema:
    type: object
    properties:
    class:
    type: string
    • committee coerce parameter in request body
    • When string in date-time format, 

    committee converts it to DateTime class

    View Slide

  56. Response validation using committee
    require "sinatra"
    require "committee"
    use Committee::Middleware::RequestValidation, schema_path: 'schema.yaml'
    use Committee::Middleware::ResponseValidation, schema_path: 'schema.yaml'
    get "/apps" do
    content_type :json
    # page should be Integer
    page = params["page"].to_i
    [page, (page*10)].to_json
    end
    This API returns string array but when returns integer array
    (we should call `map(&:to_s)` )

    View Slide

  57. require "sinatra"
    require "committee"
    use Committee::Middleware::RequestValidation, schema_path: 'schema.yaml'
    use Committee::Middleware::ResponseValidation, schema_path: 'schema.yaml'
    get "/apps" do
    content_type :json
    # page should be Integer
    page = params["page"].to_i
    [page, (page*10)].to_json
    end
    We get error response from committee
    And we can change to write log and return the response
    Response validation using committee
    % curl -X GET "http://localhost:4567/apps?page=1"
    {"id":"invalid_response","message":"1 class is Integer but it's not valid string in
    #/paths/~1apps/get/responses/200/content/application~1json/schema/items"}

    View Slide

  58. Test Assertions
    describe "GET /apps" do
    it "conforms to schema" do
    get '/apps?page=1'
    assert_schema_conform
    end
    end
    % bundle exec ruby committee_test.rb
    Run options: --seed 62877
    # Running:
    E
    Finished in 0.023367s, 42.7954 runs/s, 0.0000 assertions/s.
    1) Error:
    Committee::Middleware::Stub::GET /apps#test_0001_conforms to
    schema:
    Committee::InvalidResponse: don't exist status code definition
    in #/paths/~1apps/get/responses
    • committee provides response format checker for test
    • When there’re difference, test will fail

    View Slide

  59. committee secures the reliability
    • Committee supports request/response validation
    • We can check if it’s a valid request and response by unit test
    or integration test
    • So we can trust that the interface is correctly implemented
    along with the schema

    View Slide

  60. How to implement 

    request/response validator
    using OpenAPI 3

    View Slide

  61. Inside committee
    • The committee initially supported only JSON Hyper-Schema
    and OpenAPI 2 validation
    • So I added new validation feature using OpenAPI 3 to
    committee

    View Slide

  62. Tight coupling with JSON Hyper-
    Schema
    • committee converted OpenAPI 2 to JSON Hyper-Schema so
    committee validated one schema only
    • Validator was strongly coupled to JSON Hyper-Schema

    View Slide

  63. • OpenAPI 3 structure is different from JSON Hyper-Schema
    and
    • OpenAPI 3 have many new features (like security)
    • I decided to refactoring and implement a new validator for
    OpenAPI 3
    Implement new validator

    View Slide

  64. Refactoring in committee
    • The committee does three steps

    View Slide

  65. Refactoring in committee
    • The committee does three steps
    • Rack layer processing
    SBDLNJEEMFXBSF

    View Slide

  66. Refactoring in committee
    • The committee does three steps
    • Rack layer processing
    • Find the schema from the request
    SBDLNJEEMFXBSF
    +40/)ZQFS4DIFNB
    4DIFNB
    URL + HTTP method

    View Slide

  67. SBDLNJEEMFXBSF
    Refactoring in committee
    • The committee does three steps
    • Rack layer processing
    • Find the schema from the request
    • Validation using schema
    +40/)ZQFS4DIFNB
    7BMJEBUPS
    validate
    4DIFNB
    QBSBNFUFS

    View Slide

  68. SBDLNJEEMFXBSF
    Refactoring in committee
    • The committee does three steps
    • Rack layer processing
    • Find the schema from the request
    • Validation using schema
    +40/)ZQFS4DIFNB
    7BMJEBUPS
    validate
    4DIFNB
    QBSBNFUFS
    Depends on 

    JSON Hyper-Schema

    View Slide

  69. Refactoring schema finder
    SBDLNJEEMFXBSF
    +40/)ZQFS4DIFNB
    4DIFNB
    URL + HTTP method
    • Rack middleware pass URL and HTTP method to definition
    and get schema so don’t need to know detail of definition

    View Slide

  70. Abstracted schema definition
    • So I create abstracted schema class and made rack
    middleware depend on it
    URL + HTTP method
    %FpOJUJPO
    SBDLNJEEMFXBSF

    View Slide

  71. Abstracted schema definition
    +40/)ZQFS4DIFNB
    URL + HTTP method
    %FpOJUJPO
    SBDLNJEEMFXBSF
    • So I create abstracted schema class and made rack
    middleware depend on it
    • The middleware don’t care it’s JSON Hyper-Schema or
    OpenAPI 3

    View Slide

  72. 0QFO"1*
    Abstracted schema definition
    URL + HTTP method
    %FpOJUJPO
    SBDLNJEEMFXBSF
    • So I create abstracted schema class and made rack
    middleware depend on it
    • The middleware don’t care it’s JSON Hyper-Schema or
    OpenAPI 3

    View Slide

  73. Refactoring validator
    • Rack middleware validate using schema object from
    definition and request/response data from rack
    • But middleware don’t need to know more about schema
    SBDLNJEEMFXBSF
    7BMJEBUPS
    validate
    4DIFNB
    QBSBNFUFS
    +40/)ZQFS4DIFNB
    %FpOJUJPO

    View Slide

  74. SBDLNJEEMFXBSF
    Abstracted validator
    • I create abstracted validator which include schema definition
    • The middleware gets it from definition
    URL + HTTP method
    %FpOJUJPO
    "CTUSBDUWBMJEBUPS
    4DIFNB +40/)ZQFS4DIFNB

    +40/)ZQFS4DIFNB

    View Slide

  75. Abstracted validator
    • The middleware passes parameter to the validator for
    validation
    %FpOJUJPO
    "CTUSBDU7BMJEBUPS
    4DIFNB +40/)ZQFS4DIFNB

    +40/)ZQFS4DIFNB
    QBSBNFUFS
    validate
    SBDLNJEEMFXBSF

    View Slide

  76. Abstracted validator
    • The middleware passes parameter to the validator for
    validation
    • So rack middleware don’t need to know the definition is
    OpenAPI 3 or JSON Hyper-Schema
    %FpOJUJPO
    "CTUSBDU7BMJEBUPS
    4DIFNB 0QFO"1*

    0QFO"1*
    QBSBNFUFS
    validate
    SBDLNJEEMFXBSF

    View Slide

  77. Abstracted validator
    • The middleware passes parameter to the validator for
    validation
    • So rack middleware don’t need to know the definition is
    OpenAPI 3 or JSON Hyper-Schema
    %FpOJUJPO
    "CTUSBDU7BMJEBUPS
    4DIFNB 0QFO"1*

    0QFO"1*
    QBSBNFUFS
    validate
    SBDLNJEEMFXBSF

    View Slide

  78. openapi_parser gem
    • OpenAPI 3 parser is separated gem

    https://github.com/ota42y/openapi_parser
    • So we can implement another gem for OpenAPI 3 validation

    (e.g. more Ruby on ̋̋̋̋̋ friendly validator)
    • OpenAPI 3 parser is separated gem

    https://github.com/ota42y/openapi_parser
    • So we can implement another gem for OpenAPI 3 validation

    (e.g. more Ruby on ̋̋̋̋̋ friendly validator)

    View Slide

  79. Inside openapi_parser gem
    • OpenAPI 3 parser has 3 feature
    • Mapping definition data to Ruby object
    • Finding schema from path and HTTP method
    • Validating parameter using schema

    View Slide

  80. Mapping OpenAPI definition to object
    • OpenAPI 3 definition have many object
    openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string

    View Slide

  81. Mapping OpenAPI definition to object
    • OpenAPI 3 definition have many object
    • Definition is YAML/JSON file so 

    ruby loads it as Hash objects

    openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string

    View Slide

  82. Mapping OpenAPI definition to object
    • openapi_parser map definition data to Ruby object using DSL
    • I implemented few methods to these classes
    module OpenAPIParser::Schemas
    class Parameter < Base
    openapi_attr_values :name, :in, :description, :req
    openapi_attr_value :allow_empty_value, schema_key:
    openapi_attr_value :allow_reserved, schema_key: :a
    def validate_params(params, options)

    View Slide

  83. Inside openapi_parser gem
    • OpenAPI 3 parser has 3 feature
    • Mapping definition data to Ruby object
    • Finding schema from path and HTTP method
    • Validating parameter using schema

    View Slide

  84. %FpOJUJPO
    "CTUSBDU7BMJEBUPS
    4DIFNB 0QFO"1*

    0QFO"1*
    QBSBNFUFS
    validate
    SBDLNJEEMFXBSF
    URL + HTTP method

    View Slide

  85. openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string
    • Schema is defined separately for each HTTP
    method in Path Item Object
    Find schema from URL
    Path Item Object
    Path string

    View Slide

  86. openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string
    • Schema is defined separately for each HTTP
    method in Path Item Object
    Find schema from URL
    Path Item Object

    View Slide

  87. openapi: 3.0.0
    info:
    title: Sample API
    version: 0.1.0
    paths:
    "/apps":
    get:
    parameters:
    - name: page
    in: query
    required: true
    schema:
    type: integer
    responses:
    '200':
    description: example
    content:
    'application/json':
    schema:
    type: array
    items:
    type: string
    • Schema is defined separately for each HTTP
    method in Path Item Object
    • So we should find Path Item Object from
    requested URL
    Find schema from URL
    Path Item Object
    Path string

    View Slide

  88. OpenAPI 3 support path parameter
    paths:
    "/pets/mine":

    Requested path Definition path
    /pets/mine -> "/pets/mine"

    View Slide

  89. OpenAPI 3 support path parameter
    paths:
    "/pets/mine":

    "/pets/{petId}":

    Requested path Definition path
    /pets/mine -> "/pets/mine"
    /pets/1 -> "/pets/{petId}"
    /pets/2 -> "/pets/{petId}"

    View Slide

  90. OpenAPI 3 support path parameter
    paths:
    "/pets/mine":

    "/pets/{petId}":

    "/pets/0":

    Requested path Definition path
    /pets/mine -> "/pets/mine"
    /pets/1 -> "/pets/{petId}"
    /pets/2 -> "/pets/{petId}"
    /pets/0 -> "/pets/0"

    /pets/1/food -> "/pets/{petId}/food"
    /pets/0/food -> "/pets/0/food/"
    • If there are both with and without parameters, the one
    without parameters takes precedence

    View Slide

  91. OpenAPI 3 support path parameter
    paths:
    "/pets/mine":

    "/pets/{petId}":

    "/pets/0":

    Requested path Definition path
    /pets/mine -> "/pets/mine"
    /pets/1 -> "/pets/{petId}"
    /pets/2 -> "/pets/{petId}"
    /pets/0 -> "/pets/0"

    /pets/1/food -> "/pets/{petId}/food"
    /pets/0/food -> "/pets/0/food/"
    • If there are both with and without parameters, the one
    without parameters takes precedence
    • So we should find Path Item Object according this rule

    View Slide

  92. Support many API
    • If we are using JSON Hyper-Schema in committee, do the
    same thing but it was a full search
    • But we have many API ( One server had up to 500 APIs)
    • So we want to more efficient data structure

    View Slide

  93. • Patricia tree is space-optimized trie tree
    • All nodes have string value and child node have parent’s prefix
    Patricia tree
    Patricia trie.svg: Claudio Rocchini CC-BY 2.5

    View Slide

  94. Patricia tree for path string

    View Slide

  95. • Divide defined path by `/` and create node
    Patricia tree for path string
    users
    /users/meals/me
    me
    meals

    View Slide

  96. • Divide defined path by `/` and create node
    • Build tree
    Patricia tree for path string
    users
    /users/meals/me
    me
    meals

    View Slide

  97. • Divide defined path by `/` and create node
    • Build tree
    Patricia tree for path string
    users
    meals
    me

    View Slide

  98. • Divide defined path by `/` and create node
    • Build tree
    • Add new path’s nodes
    Patricia tree for path string
    users
    /users/meals/{id}
    {id}
    meals
    users
    meals
    me

    View Slide

  99. • Divide defined path by `/` and create node
    • Build tree
    • Add new path’s nodes
    • If there is same node, skip it and use shared node
    Patricia tree for path string
    users
    meals
    me
    users {id}
    meals

    View Slide

  100. • Divide defined path by `/` and create node
    • Build tree
    • Add new path’s nodes
    • If there is same node, skip it and use shared node
    Patricia tree for path string
    users
    meals
    me
    users {id}
    meals

    View Slide

  101. • Divide defined path by `/` and create node
    • Build tree
    • Add new path’s nodes
    • If there is same node, skip it and use shared node
    Patricia tree for path string
    users
    users
    meals
    me
    {id}
    meals

    View Slide

  102. • Divide defined path by `/` and create node
    • Build tree
    • Add new path’s nodes
    • If there is same node, skip it and use shared node
    Patricia tree for path string
    users
    users
    meals
    me
    {id}
    meals

    View Slide

  103. • Divide defined path by `/` and create node
    • Build tree
    • Add new path’s nodes
    • If there is same node, skip it and use shared node
    Patricia tree for path string
    users
    {id}
    meals
    users
    meals
    me

    View Slide

  104. • Divide defined path by `/` and create node
    • Build tree
    • Add new path’s nodes
    • If there is same node, skip it and use shared node
    • Add all paths
    Patricia tree for path string
    users
    {id}
    meals
    users
    meals
    me

    View Slide

  105. Find defined path from patricia tree
    lunch
    {id}
    users
    meals
    me
    steps
    lunch
    public
    root

    View Slide

  106. lunch
    • Divide requested URL by `/` too
    • Find node from root
    {id}
    users
    meals
    me
    steps
    lunch
    /users/meals/42/lunch
    public
    root
    Find defined path from patricia tree

    View Slide

  107. lunch
    • Divide requested URL by `/` too
    • Find node from root
    Find defined path from patricia tree
    {id}
    users
    meals
    me
    steps
    lunch
    /users/meals/42/lunch
    public
    root

    View Slide

  108. lunch
    • Divide requested URL by `/` too
    • Find node from root
    Find defined path from patricia tree
    {id}
    users
    meals
    me
    steps
    lunch
    /users/meals/42/lunch
    public
    root

    View Slide

  109. lunch
    • Divide requested URL by `/` too
    • Find node from root
    Find defined path from patricia tree
    {id}
    users
    meals
    me
    steps
    lunch
    /users/meals/42/lunch
    public
    root

    View Slide

  110. lunch
    • Divide requested URL by `/` too
    • Find node from root
    • If there isn’t matched node, 

    use parameter node (OpenAPI 3 definition)
    Find defined path from patricia tree
    {id}
    users
    meals
    me
    steps
    lunch
    /users/meals/42/lunch
    public
    root

    View Slide

  111. lunch
    • Divide requested URL by `/` too
    • Find node from root
    • If there isn’t matched node, 

    use parameter node (OpenAPI 3 definition)
    Find defined path from patricia tree
    {id}
    users
    meals
    me
    steps
    lunch
    /users/meals/42/lunch
    public
    root

    View Slide

  112. lunch
    • Divide requested URL by `/` too
    • Find node from root
    • If there isn’t matched node, 

    use parameter node (OpenAPI 3 definition)
    Find defined path from patricia tree
    {id}
    users
    meals
    me
    steps
    lunch
    /users/meals/42/lunch
    public
    root

    View Slide

  113. lunch
    • Divide requested URL by `/` too
    • Find node from root
    • If there isn’t matched node, 

    use parameter node (OpenAPI 3 definition)
    Find defined path from patricia tree
    {id}
    users
    meals
    me
    steps
    lunch
    /users/meals/42/lunch
    public
    root

    View Slide

  114. lunch
    • Divide requested URL by `/` too
    • Find node from root
    • If there isn’t matched node, 

    use parameter node (OpenAPI 3 definition)
    Find defined path from patricia tree
    {id}
    users
    meals
    me
    steps
    lunch
    /users/meals/{id}/lunch
    public
    root

    View Slide

  115. lunch
    • Divide requested URL by `/` too
    • Find node from root
    • If there isn’t matched node, 

    use parameter node (OpenAPI 3 definition)
    • Get Path Item Object from matched
    Find defined path from patricia tree
    {id}
    users
    meals
    me
    steps
    lunch
    /users/meals/{id}/lunch
    public
    root

    View Slide

  116. %FpOJUJPO
    "CTUSBDU7BMJEBUPS
    4DIFNB 0QFO"1*

    0QFO"1*
    QBSBNFUFS
    validate
    SBDLNJEEMFXBSF
    URL + HTTP method

    View Slide

  117. • When we find a schema, we can validate the parameter
    • OpenAPI 3 schema is subset of the JSON Schema Specification
    Wright Draft 00
    Parameter validation

    View Slide

  118. schema:
    type: object
    nullable: false
    properties:
    nickname:
    type: string
    string, boolean, integer
    • There are few types of schema in JSON Schema
    Parameter validation
    schema:
    type: string
    format: email
    schema:
    type: array
    items:
    type: object
    required:
    - id
    properties:
    id:
    type: integer
    object
    array

    View Slide

  119. • JSON Schema has `string`, `boolean`, `integer` type
    • These can be mapped same Ruby class so it’s easy to check
    Standard validation
    schema:
    type: string
    format: email

    View Slide

  120. • JSON Schema has `object` type
    Object validation
    schema:
    type: object
    nullable: false
    properties:
    nickname:
    type: string

    View Slide

  121. • JSON Schema has `object` type
    • This type has `properties` which has property name and schema
    Object validation
    schema:
    type: object
    nullable: false
    properties:
    nickname:
    type: string

    View Slide

  122. • JSON Schema has `object` type
    • This type has `properties` which has property name and schema
    • This type can be mapped to Hash in ruby 

    and property name is represented as hash key
    Object validation
    schema:
    type: object
    nullable: false
    properties:
    nickname:
    type: string

    View Slide

  123. • JSON Schema has `object` type
    • This type has `properties` which has property name and schema
    • This type can be mapped to Hash in ruby 

    and property name is represented as hash key
    Object validation
    schema:
    type: object
    nullable: false
    properties:
    nickname:
    type: string
    schema.properties.each do |name, child_schema|
    child_schema.validate(parameter[name])
    end

    View Slide

  124. • The `array` type in JSON Schema which can be mapped Array
    Array validation
    schema:
    type: array
    items:
    type: object
    required:
    ...

    View Slide

  125. • The `array` type in JSON Schema which can be mapped Array
    • The `array` type has items schema definition
    Array validation
    schema:
    type: array
    items:
    type: object
    required:
    ...

    View Slide

  126. • The `array` type in JSON Schema which can be mapped Array
    • The `array` type has items schema definition
    • Check all item in array is according to schema
    Array validation
    schema:
    type: array
    items:
    type: object
    required:
    ...
    array_parameter.all? do |item|
    items_schema.validate(item)
    end

    View Slide

  127. openapi_parser include these methods
    • These feature is implemented in openapi_parser

    and it’s separated from committee

    View Slide

  128. openapi_parser include these methods
    • These feature is implemented in openapi_parser

    and it’s separated from committee
    # load OpenAPI 3 definition
    root = OpenAPIParser.parse(YAML.load_file('open_api_3/schema.yml'))

    View Slide

  129. openapi_parser include these methods
    • These feature is implemented in openapi_parser

    and it’s separated from committee
    # load OpenAPI 3 definition
    root = OpenAPIParser.parse(YAML.load_file('open_api_3/schema.yml'))
    # get schema from HTTP method (POST) and path (/validate)
    op = root.request_operation(:post, '/validate')

    View Slide

  130. openapi_parser include these methods
    • These feature is implemented in openapi_parser

    and it’s separated from committee
    # load OpenAPI 3 definition
    root = OpenAPIParser.parse(YAML.load_file('open_api_3/schema.yml'))
    # get schema from HTTP method (POST) and path (/validate)
    op = root.request_operation(:post, '/validate')
    # validate request body
    ret = op.validate_request_body('application/json', params)

    View Slide

  131. openapi_parser include these methods
    • These feature is implemented in openapi_parser

    and it’s separated from committee
    • So if you want to create OpenAPI 3 tool, this gem help for you
    # load OpenAPI 3 definition
    root = OpenAPIParser.parse(YAML.load_file('open_api_3/schema.yml'))
    # get schema from HTTP method (POST) and path (/validate)
    op = root.request_operation(:post, '/validate')
    # validate request body
    ret = op.validate_request_body('application/json', params)

    View Slide

  132. Other OpenAPI 3 tools

    View Slide

  133. Client library generation

    View Slide

  134. OpenAPI Generator
    • Generate API client and Server stub from OpenAPI definition
    • Many language and framework supported
    (OpenAPI Generator is a folk of Swagger Codegen)

    View Slide

  135. Generate Ruby gem
    • This generator generates API client library as gem
    • You can try this command (using docker)
    % docker run --rm -w /local -v ${PWD}:/local openapitools/openapi-generator-cli \
    generate \
    -i schema.yaml \
    -g ruby \
    -o output_dir

    View Slide

  136. Generated gem
    • One method is created for one HTTP method definition
    api_instance = OpenapiClient::DefaultApi.new
    page = 56
    result = api_instance.apps_get(page)

    View Slide

  137. Generated gem
    • One method is created for one HTTP method definition
    api_instance = OpenapiClient::DefaultApi.new
    page = 56
    result = api_instance.apps_get(page)
    GET /apps

    View Slide

  138. Generated gem
    • One method is created for one HTTP method
    • If you want to divide by namespace, use tags in OpenAPI 3

    (OpenAPI 3 allow add tag per HTTP method)
    api_instance = OpenapiClient::DefaultApi.new
    page = 56
    result = api_instance.apps_get(page)
    users_api = OpenapiClient::UsersApi.new
    limit = 10
    users_api.blogs_get(limit)

    View Slide

  139. Document Included
    • OpenAPI 3 supports markdown description for many objects
    • OpenAPI Generator convert request / response parameter as
    method argument and return value and outputs these as
    YARD style comments with description
    # get app names by array
    # @param page specific page setting
    # @param [Hash] opts the optional parameters
    # @return [Array]
    def apps_get(page, opts = {})

    View Slide

  140. Generete type definition…?
    • I think we can generate type definition (.rbi)
    class DefaultApi
    def apps_get: (page: Integer) -> Array
    end

    View Slide

  141. Generete type definition…?
    • I think we can generate type definition (.rbi)
    • And we can generate server side code like Hanami with .rbi
    class DefaultApi
    def apps_get: (page: Integer) -> Array
    end
    module Web
    module Controllers
    module Home
    class Index
    include Web::Action
    def call(params)
    end
    end

    View Slide

  142. Interactive Document
    • Swagger UI provide 

    interactive document 

    (but no Ruby… )
    • It provides human-readable

    documents and the ability to

    try out a request

    View Slide

  143. Interactive Editor
    • Swagger Editor provide interactive editor

    View Slide

  144. If there is time, I’m going to demo

    View Slide

  145. Convert OpenAPI 2 to OpenAPI 3
    • There is OpenAPI 2 to OpenAPI 3 converter
    • https://mermade.org.uk/openapi-converter

    View Slide

  146. JSON Hyper-Schema to OpenAPI 3
    • I created JSON Hyper-Schema to OpenAPI 3
    • https://github.com/ota42y/json_hyperscheme_to_openapi3

    View Slide

  147. JSON Hyper-Schema to OpenAPI 3
    • I created JSON Hyper-Schema to OpenAPI 3
    • https://github.com/ota42y/json_hyperscheme_to_openapi3
    • But we need additional data to convert

    View Slide

  148. JSON Hyper-Schema to OpenAPI 3
    • I created JSON Hyper-Schema to OpenAPI 3
    • https://github.com/ota42y/json_hyperscheme_to_openapi3
    • But we need additional data to convert
    • We need path parameter as additional data "/pets/{id}":
    get:
    parameters:
    - name: id
    in: path
    schema:
    type: integer

    View Slide

  149. Other tools
    • Mock server
    • Definition converter (e.g. OpenAPI 3 to protocol buffers)
    • Please see OpenAPI.Tools site

    (https://openapi.tools/)

    View Slide

  150. Summary

    View Slide

  151. Summary
    • We can use OpenAPI 3 to define API schema
    • OpenAPI 3 has various tools
    • Request/Respones validation
    • Client library generation
    • Interactive document
    • If you want to create new OpenAPI tool, it’s not so difficult

    View Slide

  152. Summary
    • We can use OpenAPI 3 to define API schema
    • OpenAPI 3 has various tools
    • Request/Respones validation
    • Client library generation
    • Interactive document
    • If you want to create new OpenAPI tool, it’s not so difficult

    View Slide

  153. Summary
    • We can use OpenAPI 3 to define API schema
    • OpenAPI 3 has various tools
    • Request/Respones validation
    • Client library generation
    • Interactive document
    • If you want to create new OpenAPI tool, it’s not so difficult

    View Slide

  154. Apache License
    Version 2.0, January 2004
    http://www.apache.org/licenses/
    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
    1. Definitions.
    "License" shall mean the terms and conditions for use, reproduction,
    and distribution as defined by Sections 1 through 9 of this document.
    "Licensor" shall mean the copyright owner or entity authorized by
    the copyright owner that is granting the License.
    "Legal Entity" shall mean the union of the acting entity and all
    other entities that control, are controlled by, or are under common
    control with that entity. For the purposes of this definition,
    "control" means (i) the power, direct or indirect, to cause the
    direction or management of such entity, whether by contract or
    otherwise, or (ii) ownership of fifty percent (50%) or more of the
    outstanding shares, or (iii) beneficial ownership of such entity.
    "You" (or "Your") shall mean an individual or Legal Entity
    exercising permissions granted by this License.
    "Source" form shall mean the preferred form for making modifications,
    including but not limited to software source code, documentation
    source, and configuration files.
    "Object" form shall mean any form resulting from mechanical
    transformation or translation of a Source form, including but
    not limited to compiled object code, generated documentation,
    and conversions to other media types.
    "Work" shall mean the work of authorship, whether in Source or
    Object form, made available under the License, as indicated by a
    copyright notice that is included in or attached to the work
    (an example is provided in the Appendix below).
    "Derivative Works" shall mean any work, whether in Source or Object
    form, that is based on (or derived from) the Work and for which the
    editorial revisions, annotations, elaborations, or other modifications
    represent, as a whole, an original work of authorship. For the purposes
    of this License, Derivative Works shall not include works that remain
    separable from, or merely link (or bind by name) to the interfaces of,
    the Work and Derivative Works thereof.
    "Contribution" shall mean any work of authorship, including
    the original version of the Work and any modifications or additions
    to that Work or Derivative Works thereof, that is intentionally
    submitted to Licensor for inclusion in the Work by the copyright owner
    or by an individual or Legal Entity authorized to submit on behalf of
    the copyright owner. For the purposes of this definition, "submitted"
    means any form of electronic, verbal, or written communication sent
    to the Licensor or its representatives, including but not limited to
    communication on electronic mailing lists, source code control systems,
    and issue tracking systems that are managed by, or on behalf of, the
    Licensor for the purpose of discussing and improving the Work, but
    excluding communication that is conspicuously marked or otherwise
    designated in writing by the copyright owner as "Not a Contribution."
    "Contributor" shall mean Licensor and any individual or Legal Entity
    on behalf of whom a Contribution has been received by Licensor and
    subsequently incorporated within the Work.
    2. Grant of Copyright License. Subject to the terms and conditions of
    this License, each Contributor hereby grants to You a perpetual,
    worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    copyright license to reproduce, prepare Derivative Works of,
    publicly display, publicly perform, sublicense, and distribute the
    Work and such Derivative Works in Source or Object form.
    3. Grant of Patent License. Subject to the terms and conditions of
    this License, each Contributor hereby grants to You a perpetual,
    worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    (except as stated in this section) patent license to make, have made,
    use, offer to sell, sell, import, and otherwise transfer the Work,
    where such license applies only to those patent claims licensable
    by such Contributor that are necessarily infringed by their
    Contribution(s) alone or by combination of their Contribution(s)
    with the Work to which such Contribution(s) was submitted. If You
    institute patent litigation against any entity (including a
    cross-claim or counterclaim in a lawsuit) alleging that the Work
    or a Contribution incorporated within the Work constitutes direct
    or contributory patent infringement, then any patent licenses
    granted to You under this License for that Work shall terminate
    as of the date such litigation is filed.
    4. Redistribution. You may reproduce and distribute copies of the
    Work or Derivative Works thereof in any medium, with or without
    modifications, and in Source or Object form, provided that You
    meet the following conditions:
    (a) You must give any other recipients of the Work or
    Derivative Works a copy of this License; and
    (b) You must cause any modified files to carry prominent notices
    stating that You changed the files; and
    (c) You must retain, in the Source form of any Derivative Works
    that You distribute, all copyright, patent, trademark, and
    attribution notices from the Source form of the Work,
    excluding those notices that do not pertain to any part of
    the Derivative Works; and
    (d) If the Work includes a "NOTICE" text file as part of its
    distribution, then any Derivative Works that You distribute must
    include a readable copy of the attribution notices contained
    within such NOTICE file, excluding those notices that do not
    pertain to any part of the Derivative Works, in at least one
    of the following places: within a NOTICE text file distributed
    as part of the Derivative Works; within the Source form or
    documentation, if provided along with the Derivative Works; or,
    within a display generated by the Derivative Works, if and
    wherever such third-party notices normally appear. The contents
    of the NOTICE file are for informational purposes only and
    do not modify the License. You may add Your own attribution
    notices within Derivative Works that You distribute, alongside
    or as an addendum to the NOTICE text from the Work, provided
    that such additional attribution notices cannot be construed
    as modifying the License.
    You may add Your own copyright statement to Your modifications and
    may provide additional or different license terms and conditions
    for use, reproduction, or distribution of Your modifications, or
    for any such Derivative Works as a whole, provided Your use,
    reproduction, and distribution of the Work otherwise complies with
    the conditions stated in this License.
    5. Submission of Contributions. Unless You explicitly state otherwise,
    any Contribution intentionally submitted for inclusion in the Work
    by You to the Licensor shall be under the terms and conditions of
    this License, without any additional terms or conditions.
    Notwithstanding the above, nothing herein shall supersede or modify
    the terms of any separate license agreement you may have executed
    with Licensor regarding such Contributions.
    6. Trademarks. This License does not grant permission to use the trade
    names, trademarks, service marks, or product names of the Licensor,
    except as required for reasonable and customary use in describing the
    origin of the Work and reproducing the content of the NOTICE file.
    7. Disclaimer of Warranty. Unless required by applicable law or
    agreed to in writing, Licensor provides the Work (and each
    Contributor provides its Contributions) on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    implied, including, without limitation, any warranties or conditions
    of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
    PARTICULAR PURPOSE. You are solely responsible for determining the
    appropriateness of using or redistributing the Work and assume any
    risks associated with Your exercise of permissions under this License.
    8. Limitation of Liability. In no event and under no legal theory,
    whether in tort (including negligence), contract, or otherwise,
    unless required by applicable law (such as deliberate and grossly
    negligent acts) or agreed to in writing, shall any Contributor be
    liable to You for damages, including any direct, indirect, special,
    incidental, or consequential damages of any character arising as a
    result of this License or out of the use or inability to use the
    Work (including but not limited to damages for loss of goodwill,
    work stoppage, computer failure or malfunction, or any and all
    other commercial damages or losses), even if such Contributor
    has been advised of the possibility of such damages.
    9. Accepting Warranty or Additional Liability. While redistributing
    the Work or Derivative Works thereof, You may choose to offer,
    and charge a fee for, acceptance of support, warranty, indemnity,
    or other liability obligations and/or rights consistent with this
    License. However, in accepting such obligations, You may act only
    on Your own behalf and on Your sole responsibility, not on behalf
    of any other Contributor, and only if You agree to indemnify,
    defend, and hold each Contributor harmless for any liability
    incurred by, or claims asserted against, such Contributor by reason
    of your accepting any such warranty or additional liability.
    END OF TERMS AND CONDITIONS
    APPENDIX: How to apply the Apache License to your work.
    To apply the Apache License to your work, attach the following
    boilerplate notice, with the fields enclosed by brackets "{}"
    replaced with your own identifying information. (Don't include
    the brackets!) The text should be enclosed in the appropriate
    comment syntax for the file format. We also recommend that a
    file or class name and description of purpose be included on the
    same "printed page" as the copyright notice for easier
    identification within third-party archives.
    Copyright The Linux Foundation
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

    View Slide

  155. Additional slides

    (I added after the end 

    There is answers for Q&A)

    View Slide

  156. Do you use committee in production?
    • Yes
    • We use request validator and coerce all value in production
    • But we don’t use response validator in production, we use staging only
    • Because if we implement request/response by correct in staging, we
    don’t need check in production
    • committee has parameter coercer so we use request validation in
    production

    View Slide

  157. Committee is slow?
    • It is a benchmark result
    • Small benchmark have 1 query parameter
    • Big benchmark have 2600 objects
    • Check enable/disable committee and request 1000 times
    • I don’t check response validation benchmark because we don’t use it in production
    • Benchmark script is here

    https://gist.github.com/ota42y/3ed68a2cb0dc7c98122bdfd1a696ab72

    View Slide

  158. Small result
    • 1000 times request
    • So committee need 0.2 milliseconds in every request
    VTFS TZTUFN UPUBM SFBM
    /PU6TF
    6TF

    View Slide

  159. Big result
    • Validate 2600 objects by 6 milliseconds

    ( In many cases, it is about 100 at most, so I think that there is no
    problem)
    VTFS TZTUFN UPUBM SFBM
    /PU6TF
    6TF

    View Slide