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

The quickest way to stable API in Laravel

The quickest way to stable API in Laravel

Builiding API using great combination of tools and workflows how we can vastly speedup and improve our API development, without compromising stability and testability.

Milan Popović

March 23, 2016
Tweet

More Decks by Milan Popović

Other Decks in Programming

Transcript

  1. THE QUICKEST WAY TO
    STABLE API
    USING LARAVEL FRAMEWORK
    Presented by /
    Milan Popović @komita1981

    View Slide

  2. ME
    PHP developer
    Work for Navus Consulting Gmbh
    I like to learn and share knowledge
    Active member of PHP Srbija

    View Slide

  3. Why Laravel?
    Enables rapid development
    Stable and well tested
    Community support
    Documentation
    Learning resources
    Easy to recruit developers
    LTS

    View Slide

  4. Why Laravel for quick API development?
    DB Migration
    DB seeding
    Model factory
    Form request
    Testing
    3rd Party Packages

    View Slide

  5. DB MIGRATION
    Version control for you DB schema
    Laravel Schema facade provides database agnostic support
    for creating and manipulating tables
    /
    / C
    r
    e
    a
    t
    e n
    e
    w m
    i
    g
    r
    a
    t
    i
    o
    n
    p
    h
    p a
    r
    t
    i
    s
    a
    n m
    a
    k
    e
    :
    m
    i
    g
    r
    a
    t
    i
    o
    n c
    r
    e
    a
    t
    e
    _
    u
    s
    e
    r
    s
    _
    t
    a
    b
    l
    e
    /
    / R
    u
    n m
    i
    g
    r
    a
    t
    i
    o
    n
    p
    h
    p a
    r
    t
    i
    s
    a
    n m
    i
    g
    r
    a
    t
    e
    /
    / R
    o
    l
    l
    b
    a
    c
    k m
    i
    g
    r
    a
    t
    i
    o
    n
    p
    h
    p a
    r
    t
    i
    s
    a
    n m
    i
    g
    r
    a
    t
    e

    View Slide

  6. DB SEED
    Sample/Test data for your DB
    /
    / C
    r
    e
    a
    t
    e n
    e
    w s
    e
    e
    d
    e
    r
    p
    h
    p a
    r
    t
    i
    s
    a
    n m
    a
    k
    e
    :
    s
    e
    e
    d
    e
    r U
    s
    e
    r
    s
    T
    a
    b
    l
    e
    S
    e
    e
    d
    e
    r
    /
    / R
    u
    n s
    e
    e
    d
    e
    r
    s
    p
    h
    p a
    r
    t
    i
    s
    a
    n d
    b
    :
    s
    e
    e
    d
    /
    / R
    u
    n s
    e
    e
    d
    e
    r
    s v
    2
    p
    h
    p a
    r
    t
    i
    s
    a
    n m
    i
    g
    r
    a
    t
    e -
    -
    s
    e
    e
    d
    /
    / R
    u
    n s
    i
    n
    g
    l
    e s
    e
    e
    d
    e
    r
    p
    h
    p a
    r
    t
    i
    s
    a
    n d
    b
    :
    s
    e
    e
    d -
    -
    c
    l
    a
    s
    s
    =
    U
    s
    e
    r
    s
    T
    a
    b
    l
    e
    S
    e
    e
    d
    e
    r

    View Slide

  7. MODEL FACTORY
    Default model attributes
    Uses Faker for generating values
    $
    f
    a
    c
    t
    o
    r
    y
    -
    >
    d
    e
    f
    i
    n
    e
    (
    A
    p
    p
    \
    U
    s
    e
    r
    :
    :
    c
    l
    a
    s
    s
    , f
    u
    n
    c
    t
    i
    o
    n (
    F
    a
    k
    e
    r
    \
    G
    e
    n
    e
    r
    a
    t
    o
    r $
    f
    a
    k
    e
    r
    ) {
    r
    e
    t
    u
    r
    n [
    '
    n
    a
    m
    e
    ' =
    > $
    f
    a
    k
    e
    r
    -
    >
    n
    a
    m
    e
    ,
    '
    e
    m
    a
    i
    l
    ' =
    > $
    f
    a
    k
    e
    r
    -
    >
    e
    m
    a
    i
    l
    ,
    '
    p
    a
    s
    s
    w
    o
    r
    d
    ' =
    > b
    c
    r
    y
    p
    t
    (
    s
    t
    r
    _
    r
    a
    n
    d
    o
    m
    (
    1
    0
    )
    )
    ,
    '
    r
    e
    m
    e
    m
    b
    e
    r
    _
    t
    o
    k
    e
    n
    ' =
    > s
    t
    r
    _
    r
    a
    n
    d
    o
    m
    (
    1
    0
    )
    ,
    ]
    ;
    }
    )
    ;

    View Slide

  8. Multiple Factory Types - multiple factories for the same
    Eloquent model class
    $
    f
    a
    c
    t
    o
    r
    y
    -
    >
    d
    e
    f
    i
    n
    e
    A
    s
    (
    A
    p
    p
    \
    U
    s
    e
    r
    :
    :
    c
    l
    a
    s
    s
    , '
    a
    d
    m
    i
    n
    '
    , f
    u
    n
    c
    t
    i
    o
    n (
    $
    f
    a
    k
    e
    r
    ) u
    s
    e (
    $
    f
    a
    c
    t
    o
    r
    y
    $
    u
    s
    e
    r = $
    f
    a
    c
    t
    o
    r
    y
    -
    >
    r
    a
    w
    (
    A
    p
    p
    \
    U
    s
    e
    r
    :
    :
    c
    l
    a
    s
    s
    )
    ;
    r
    e
    t
    u
    r
    n a
    r
    r
    a
    y
    _
    m
    e
    r
    g
    e
    (
    $
    u
    s
    e
    r
    , [
    '
    a
    d
    m
    i
    n
    ' =
    > t
    r
    u
    e
    ]
    )
    ;
    }
    )
    ;

    View Slide

  9. Attach relationships
    $
    f
    a
    c
    t
    o
    r
    y
    -
    >
    d
    e
    f
    i
    n
    e
    (
    A
    p
    p
    \
    P
    o
    s
    t
    :
    :
    c
    l
    a
    s
    s
    , f
    u
    n
    c
    t
    i
    o
    n (
    $
    f
    a
    k
    e
    r
    ) {
    r
    e
    t
    u
    r
    n [
    '
    t
    i
    t
    l
    e
    ' =
    > $
    f
    a
    k
    e
    r
    -
    >
    t
    i
    t
    l
    e
    ,
    '
    c
    o
    n
    t
    e
    n
    t
    ' =
    > $
    f
    a
    k
    e
    r
    -
    >
    p
    a
    r
    a
    g
    r
    a
    p
    h
    ,
    '
    u
    s
    e
    r
    _
    i
    d
    ' =
    > f
    u
    n
    c
    t
    i
    o
    n (
    ) {
    r
    e
    t
    u
    r
    n f
    a
    c
    t
    o
    r
    y
    (
    A
    p
    p
    \
    U
    s
    e
    r
    :
    :
    c
    l
    a
    s
    s
    )
    -
    >
    c
    r
    e
    a
    t
    e
    (
    )
    -
    >
    i
    d
    ;
    }
    ,
    '
    u
    s
    e
    r
    _
    t
    y
    p
    e
    ' =
    > f
    u
    n
    c
    t
    i
    o
    n (
    a
    r
    r
    a
    y $
    p
    o
    s
    t
    ) {
    r
    e
    t
    u
    r
    n A
    p
    p
    \
    U
    s
    e
    r
    :
    :
    f
    i
    n
    d
    (
    $
    p
    o
    s
    t
    [
    '
    u
    s
    e
    r
    _
    i
    d
    '
    ]
    )
    -
    >
    t
    y
    p
    e
    ;
    }
    ]
    ;
    }
    )
    ;

    View Slide

  10. Using factories
    /
    / C
    r
    e
    a
    t
    e t
    h
    r
    e
    e A
    p
    p
    \
    U
    s
    e
    r i
    n
    s
    t
    a
    n
    c
    e
    s
    .
    .
    .
    $
    u
    s
    e
    r
    s = f
    a
    c
    t
    o
    r
    y
    (
    A
    p
    p
    \
    U
    s
    e
    r
    :
    :
    c
    l
    a
    s
    s
    , 3
    )
    -
    >
    m
    a
    k
    e
    (
    )
    ;
    /
    / C
    r
    e
    a
    t
    e t
    h
    r
    e
    e A
    p
    p
    \
    U
    s
    e
    r "
    a
    d
    m
    i
    n
    " i
    n
    s
    t
    a
    n
    c
    e
    s
    .
    .
    .
    $
    u
    s
    e
    r
    s = f
    a
    c
    t
    o
    r
    y
    (
    A
    p
    p
    \
    U
    s
    e
    r
    :
    :
    c
    l
    a
    s
    s
    , '
    a
    d
    m
    i
    n
    '
    , 3
    )
    -
    >
    m
    a
    k
    e
    (
    )
    ;
    /
    / C
    r
    e
    a
    t
    e A
    p
    p
    \
    U
    s
    e
    r u
    s
    e
    r w
    i
    t
    h g
    i
    v
    e
    n n
    a
    m
    e
    .
    .
    .
    $
    u
    s
    e
    r = f
    a
    c
    t
    o
    r
    y
    (
    A
    p
    p
    \
    U
    s
    e
    r
    :
    :
    c
    l
    a
    s
    s
    )
    -
    >
    m
    a
    k
    e
    (
    [
    '
    n
    a
    m
    e
    ' =
    > '
    A
    b
    i
    g
    a
    i
    l
    '
    ,
    ]
    )
    ;
    /
    / P
    e
    r
    s
    i
    s
    t
    i
    n
    g F
    a
    c
    t
    o
    r
    y M
    o
    d
    e
    l
    s
    $
    u
    s
    e
    r = f
    a
    c
    t
    o
    r
    y
    (
    A
    p
    p
    \
    U
    s
    e
    r
    :
    :
    c
    l
    a
    s
    s
    )
    -
    >
    c
    r
    e
    a
    t
    e
    (
    )
    ;

    View Slide

  11. FORM REQUESTS
    Special class for validating request params and authorizing
    Each class has rules() (returns array) and authorize() (returns
    boolean) methods
    Type Hinting in Controller methods

    View Slide

  12. p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n r
    u
    l
    e
    s
    (
    )
    {
    r
    e
    t
    u
    r
    n [
    '
    t
    i
    t
    l
    e
    ' =
    > '
    r
    e
    q
    u
    i
    r
    e
    d
    |
    u
    n
    i
    q
    u
    e
    :
    p
    o
    s
    t
    s
    |
    m
    a
    x
    :
    2
    5
    5
    '
    ,
    '
    b
    o
    d
    y
    ' =
    > '
    r
    e
    q
    u
    i
    r
    e
    d
    '
    ,
    ]
    ;
    }
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n a
    u
    t
    h
    o
    r
    i
    z
    e
    (
    )
    {
    $
    c
    o
    m
    m
    e
    n
    t
    I
    d = $
    t
    h
    i
    s
    -
    >
    r
    o
    u
    t
    e
    (
    '
    c
    o
    m
    m
    e
    n
    t
    '
    )
    ;
    r
    e
    t
    u
    r
    n C
    o
    m
    m
    e
    n
    t
    :
    :
    w
    h
    e
    r
    e
    (
    '
    i
    d
    '
    , $
    c
    o
    m
    m
    e
    n
    t
    I
    d
    )
    -
    >
    w
    h
    e
    r
    e
    (
    '
    u
    s
    e
    r
    _
    i
    d
    '
    , A
    u
    t
    h
    :
    :
    i
    d
    (
    )
    )
    -
    >
    e
    x
    i
    s
    t
    s
    (
    )
    ;
    }

    View Slide

  13. TESTING
    PHPUnit is included out of the box
    Laravel is built with testing in mind
    It's also ships with convenient helper methods
    Uses Mockery as mock object framework

    View Slide

  14. WORKING WITH DATABASE
    Using Migrations - DatabaseMigrations trait
    DatabaseTransactions - DatabaseTransactions trait
    Model Factories

    View Slide

  15. WORKING WITH DATABASE
    SeeInDatabase helper
    seeInDatabase($table, array $data, $connection = null)
    NotSeeInDatabase helper
    notSeeInDatabase($table, array $data, $connection = null)
    Seed (seed($class = 'DatabaseSeeder')

    View Slide

  16. CREATING HTTP REQUEST
    /
    / M
    a
    i
    n m
    e
    t
    h
    o
    d
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n c
    a
    l
    l
    (
    $
    m
    e
    t
    h
    o
    d
    , $
    u
    r
    i
    , $
    p
    a
    r
    a
    m
    e
    t
    e
    r
    s = [
    ]
    , $
    c
    o
    o
    k
    i
    e
    s = [
    ]
    , $
    f
    i
    l
    e
    s =
    /
    / T
    h
    e
    r
    e a
    r
    e a
    l
    s
    o m
    e
    t
    h
    o
    d
    s f
    o
    r o
    t
    h
    e
    r h
    t
    t
    p v
    e
    r
    b
    s
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n p
    o
    s
    t
    (
    $
    u
    r
    i
    , a
    r
    r
    a
    y $
    d
    a
    t
    a = [
    ]
    , a
    r
    r
    a
    y $
    h
    e
    a
    d
    e
    r
    s = [
    ]
    )
    /
    / V
    i
    s
    i
    t t
    h
    e g
    i
    v
    e
    n U
    R
    I w
    i
    t
    h a J
    S
    O
    N r
    e
    q
    u
    e
    s
    t
    .
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n j
    s
    o
    n
    (
    $
    m
    e
    t
    h
    o
    d
    , $
    u
    r
    i
    , a
    r
    r
    a
    y $
    d
    a
    t
    a = [
    ]
    , a
    r
    r
    a
    y $
    h
    e
    a
    d
    e
    r
    s = [
    ]
    )
    {
    /
    / r
    e
    m
    o
    v
    e
    d c
    o
    d
    e f
    r
    o
    m o
    r
    i
    g
    i
    n
    a
    l m
    e
    t
    h
    o
    d
    $
    c
    o
    n
    t
    e
    n
    t = j
    s
    o
    n
    _
    e
    n
    c
    o
    d
    e
    (
    $
    d
    a
    t
    a
    )
    ;
    $
    h
    e
    a
    d
    e
    r
    s = a
    r
    r
    a
    y
    _
    m
    e
    r
    g
    e
    (
    [
    '
    C
    O
    N
    T
    E
    N
    T
    _
    L
    E
    N
    G
    T
    H
    ' =
    > m
    b
    _
    s
    t
    r
    l
    e
    n
    (
    $
    c
    o
    n
    t
    e
    n
    t
    , '
    8
    b
    i
    t
    '
    )
    ,
    '
    C
    O
    N
    T
    E
    N
    T
    _
    T
    Y
    P
    E
    ' =
    > '
    a
    p
    p
    l
    i
    c
    a
    t
    i
    o
    n
    /
    j
    s
    o
    n
    '
    ,
    '
    A
    c
    c
    e
    p
    t
    ' =
    > '
    a
    p
    p
    l
    i
    c
    a
    t
    i
    o
    n
    /
    j
    s
    o
    n
    '
    ,
    ]
    , $
    h
    e
    a
    d
    e
    r
    s
    )
    ;

    View Slide

  17. PHPUNIT ASSERTIONS FOR STATUS
    CODE AND HEADERS
    assertResponseOk()
    assertResponseStatus($code)
    seeStatusCode($status)
    seeHeader($headerName, $value)

    View Slide

  18. PHPUNIT ASSERTIONS FOR JSON
    seeJsonEquals($data)
    seeJsonStructure($structure, $responseData)
    seeJsonContains($data, $negate)
    seeJsonSubset($data)

    View Slide

  19. PACKAGES & TOOLS
    Dingo API
    Dredd
    Repositories
    CORS

    View Slide

  20. DINGO API
    "
    r
    e
    q
    u
    i
    r
    e
    "
    : {
    "
    d
    i
    n
    g
    o
    /
    a
    p
    i
    "
    : "
    1
    .
    0
    .
    *
    @
    d
    e
    v
    "
    }
    Provides set of tools to easily and quickly build your own API
    Requires Laravel 5.1+ or Lumen 5.1+ and PHP 5.5.9+

    View Slide

  21. CONFIGURATION
    Much of the package comes preconfigured
    Use your .env file to configure most of the package
    Finer tuning of the package will require publishing the
    configuration file

    View Slide

  22. Configure:
    Name
    Default Version
    Authentication Provider
    Throttling / Rate Limiting (Disabled by default)
    Response Transformer (Fractal is the default)
    Response Format (JSON and a JSON response format is
    registered by default)
    Error Format

    View Slide

  23. CREATING API ENDPOINTS
    /
    / T
    o a
    v
    o
    i
    d c
    o
    m
    p
    l
    i
    c
    a
    t
    i
    o
    n
    s w
    i
    t
    h y
    o
    u
    r m
    a
    i
    n a
    p
    p
    l
    i
    c
    a
    t
    i
    o
    n r
    o
    u
    t
    e
    s t
    h
    i
    s p
    a
    c
    k
    a
    g
    e u
    t
    i
    l
    $
    a
    p
    i = a
    p
    p
    (
    '
    D
    i
    n
    g
    o
    \
    A
    p
    i
    \
    R
    o
    u
    t
    i
    n
    g
    \
    R
    o
    u
    t
    e
    r
    '
    )
    ;
    $
    a
    p
    i
    -
    >
    v
    e
    r
    s
    i
    o
    n
    (
    '
    v
    1
    '
    ,
    f
    u
    n
    c
    t
    i
    o
    n (
    $
    a
    p
    i
    ) {
    $
    a
    p
    i
    -
    >
    p
    o
    s
    t
    (
    '
    r
    e
    g
    i
    s
    t
    e
    r
    '
    , '
    S
    a
    m
    p
    l
    e
    A
    p
    i
    \
    H
    t
    t
    p
    \
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    s
    \
    R
    e
    g
    i
    s
    t
    e
    r
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    $
    a
    p
    i
    -
    >
    p
    o
    s
    t
    (
    '
    l
    o
    g
    i
    n
    '
    , '
    S
    a
    m
    p
    l
    e
    A
    p
    i
    \
    H
    t
    t
    p
    \
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    s
    \
    L
    o
    g
    i
    n
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    @
    l
    o
    g
    i
    n
    $
    a
    p
    i
    -
    >
    g
    e
    t
    (
    '
    b
    l
    o
    c
    k
    s
    '
    , '
    S
    a
    m
    p
    l
    e
    A
    p
    i
    \
    H
    t
    t
    p
    \
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    s
    \
    B
    l
    o
    c
    k
    s
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    @
    g
    e
    t
    A
    $
    a
    p
    i
    -
    >
    g
    e
    t
    (
    '
    b
    l
    o
    c
    k
    s
    /
    {
    i
    d
    }
    '
    , '
    S
    a
    m
    p
    l
    e
    A
    p
    i
    \
    H
    t
    t
    p
    \
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    s
    \
    B
    l
    o
    c
    k
    s
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    $
    a
    p
    i
    -
    >
    p
    o
    s
    t
    (
    '
    b
    l
    o
    c
    k
    s
    '
    , '
    S
    a
    m
    p
    l
    e
    A
    p
    i
    \
    H
    t
    t
    p
    \
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    s
    \
    B
    l
    o
    c
    k
    s
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    @
    c
    r
    e
    $
    a
    p
    i
    -
    >
    p
    u
    t
    (
    '
    b
    l
    o
    c
    k
    s
    /
    {
    i
    d
    }
    '
    , '
    S
    a
    m
    p
    l
    e
    A
    p
    i
    \
    H
    t
    t
    p
    \
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    s
    \
    B
    l
    o
    c
    k
    s
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    $
    a
    p
    i
    -
    >
    d
    e
    l
    e
    t
    e
    (
    '
    b
    l
    o
    c
    k
    s
    /
    {
    i
    d
    }
    '
    , '
    S
    a
    m
    p
    l
    e
    A
    p
    i
    \
    H
    t
    t
    p
    \
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    s
    \
    B
    l
    o
    c
    k
    s
    C
    o
    n
    t
    r
    o
    l
    }
    )
    ;

    View Slide

  24. RESPONSES
    There's a number of different ways to return responses
    Use Response Builder
    Provides a fluent interface to easily build a more
    customizable response
    Generally used in conjunction with transformers.
    Use the Dingo\Api\Routing\Helpers trait

    View Slide

  25. u
    s
    e D
    i
    n
    g
    o
    \
    A
    p
    i
    \
    R
    o
    u
    t
    i
    n
    g
    \
    H
    e
    l
    p
    e
    r
    s
    ;
    u
    s
    e I
    l
    l
    u
    m
    i
    n
    a
    t
    e
    \
    R
    o
    u
    t
    i
    n
    g
    \
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    ;
    c
    l
    a
    s
    s A
    p
    i
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r e
    x
    t
    e
    n
    d
    s C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    {
    u
    s
    e H
    e
    l
    p
    e
    r
    s
    ;
    }

    View Slide

  26. RESPONDING WITH AN ARRAY
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n s
    h
    o
    w
    (
    $
    i
    d
    )
    {
    $
    b
    l
    o
    c
    k = $
    t
    h
    i
    s
    -
    >
    b
    l
    o
    c
    k
    -
    >
    f
    i
    n
    d
    (
    $
    i
    d
    )
    ;
    r
    e
    t
    u
    r
    n $
    t
    h
    i
    s
    -
    >
    r
    e
    s
    p
    o
    n
    s
    e
    -
    >
    a
    r
    r
    a
    y
    (
    $
    b
    l
    o
    c
    k
    -
    >
    t
    o
    A
    r
    r
    a
    y
    (
    )
    )
    ;
    }

    View Slide

  27. RESPONDING WITH A SINGLE ITEM
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n s
    h
    o
    w
    (
    $
    i
    d
    )
    {
    $
    b
    l
    o
    c
    k = $
    t
    h
    i
    s
    -
    >
    b
    l
    o
    c
    k
    -
    >
    f
    i
    n
    d
    (
    $
    i
    d
    )
    ;
    r
    e
    t
    u
    r
    n $
    t
    h
    i
    s
    -
    >
    r
    e
    s
    p
    o
    n
    s
    e
    -
    >
    i
    t
    e
    m
    (
    $
    b
    l
    o
    c
    k
    , n
    e
    w B
    l
    o
    c
    k
    T
    r
    a
    n
    s
    f
    o
    r
    m
    e
    r
    )
    ;
    }

    View Slide

  28. RESPONDING WITH A COLLECTION OF ITEMS
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n s
    h
    o
    w
    (
    $
    i
    d
    )
    {
    $
    b
    l
    o
    c
    k
    s = $
    t
    h
    i
    s
    -
    >
    b
    l
    o
    c
    k
    -
    >
    f
    i
    n
    d
    (
    $
    i
    d
    )
    ;
    r
    e
    t
    u
    r
    n $
    t
    h
    i
    s
    -
    >
    r
    e
    s
    p
    o
    n
    s
    e
    -
    >
    c
    o
    l
    l
    e
    c
    t
    i
    o
    n
    (
    $
    b
    l
    o
    c
    k
    s
    , n
    e
    w B
    l
    o
    c
    k
    T
    r
    a
    n
    s
    f
    o
    r
    m
    e
    r
    )
    ;
    }

    View Slide

  29. RESPONDING WITH PAGINATED ITEMS
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n s
    h
    o
    w
    (
    $
    i
    d
    )
    {
    $
    b
    l
    o
    c
    k
    s = $
    t
    h
    i
    s
    -
    >
    b
    l
    o
    c
    k
    -
    >
    f
    i
    n
    d
    (
    $
    i
    d
    )
    ;
    r
    e
    t
    u
    r
    n $
    t
    h
    i
    s
    -
    >
    r
    e
    s
    p
    o
    n
    s
    e
    -
    >
    p
    a
    g
    i
    n
    a
    t
    i
    o
    n
    (
    $
    b
    l
    o
    c
    k
    s
    , n
    e
    w B
    l
    o
    c
    k
    T
    r
    a
    n
    s
    f
    o
    r
    m
    e
    r
    )
    ;
    }

    View Slide

  30. OTHER RESPONSES
    /
    / R
    e
    s
    p
    o
    n
    d
    i
    n
    g W
    i
    t
    h N
    o C
    o
    n
    t
    e
    n
    t
    r
    e
    t
    u
    r
    n $
    t
    h
    i
    s
    -
    >
    r
    e
    s
    p
    o
    n
    s
    e
    -
    >
    n
    o
    C
    o
    n
    t
    e
    n
    t
    (
    )
    ;
    /
    / R
    e
    s
    p
    o
    n
    d
    i
    n
    g W
    i
    t
    h C
    r
    e
    a
    t
    e
    d R
    e
    s
    p
    o
    n
    s
    e
    r
    e
    t
    u
    r
    n $
    t
    h
    i
    s
    -
    >
    r
    e
    s
    p
    o
    n
    s
    e
    -
    >
    c
    r
    e
    a
    t
    e
    d
    (
    )
    ;
    /
    / A g
    e
    n
    e
    r
    i
    c e
    r
    r
    o
    r w
    i
    t
    h c
    u
    s
    t
    o
    m m
    e
    s
    s
    a
    g
    e a
    n
    d s
    t
    a
    t
    u
    s c
    o
    d
    e
    .
    r
    e
    t
    u
    r
    n $
    t
    h
    i
    s
    -
    >
    r
    e
    s
    p
    o
    n
    s
    e
    -
    >
    e
    r
    r
    o
    r
    (
    '
    T
    h
    i
    s i
    s a
    n e
    r
    r
    o
    r
    .
    '
    , 4
    0
    4
    )
    ;
    /
    / A n
    o
    t f
    o
    u
    n
    d e
    r
    r
    o
    r w
    i
    t
    h a
    n o
    p
    t
    i
    o
    n
    a
    l m
    e
    s
    s
    a
    g
    e a
    s t
    h
    e f
    i
    r
    s
    t p
    a
    r
    a
    m
    e
    t
    e
    r
    .
    r
    e
    t
    u
    r
    n $
    t
    h
    i
    s
    -
    >
    r
    e
    s
    p
    o
    n
    s
    e
    -
    >
    e
    r
    r
    o
    r
    N
    o
    t
    F
    o
    u
    n
    d
    (
    )
    ;
    /
    / T
    h
    e
    r
    e a
    r
    e a
    l
    s
    o e
    r
    r
    o
    r
    B
    a
    d
    R
    e
    q
    u
    e
    s
    t
    , e
    r
    r
    o
    r
    F
    o
    r
    b
    i
    d
    d
    e
    n
    , e
    r
    r
    o
    r
    I
    n
    t
    e
    r
    n
    a
    l
    , e
    r
    r
    o
    r
    U
    n
    a
    u
    t
    h

    View Slide

  31. Adding Additional Headers
    r
    e
    t
    u
    r
    n $
    t
    h
    i
    s
    -
    >
    r
    e
    s
    p
    o
    n
    s
    e
    -
    >
    i
    t
    e
    m
    (
    $
    u
    s
    e
    r
    , n
    e
    w U
    s
    e
    r
    T
    r
    a
    n
    s
    f
    o
    r
    m
    e
    r
    )
    -
    >
    w
    i
    t
    h
    H
    e
    a
    d
    e
    r
    (
    '
    X
    -
    F
    o
    o
    '
    Adding Meta Data
    r
    e
    t
    u
    r
    n $
    t
    h
    i
    s
    -
    >
    r
    e
    s
    p
    o
    n
    s
    e
    -
    >
    i
    t
    e
    m
    (
    $
    u
    s
    e
    r
    , n
    e
    w U
    s
    e
    r
    T
    r
    a
    n
    s
    f
    o
    r
    m
    e
    r
    )
    -
    >
    a
    d
    d
    M
    e
    t
    a
    (
    '
    f
    o
    o
    '
    /
    / s
    e
    t a
    n a
    r
    r
    a
    y o
    f m
    e
    t
    a d
    a
    t
    a i
    n
    s
    t
    e
    a
    d o
    f c
    h
    a
    i
    n
    i
    n
    g m
    u
    l
    t
    i
    p
    l
    e m
    e
    t
    h
    o
    d c
    a
    l
    l
    s
    r
    e
    t
    u
    r
    n $
    t
    h
    i
    s
    -
    >
    r
    e
    s
    p
    o
    n
    s
    e
    -
    >
    i
    t
    e
    m
    (
    $
    u
    s
    e
    r
    , n
    e
    w U
    s
    e
    r
    T
    r
    a
    n
    s
    f
    o
    r
    m
    e
    r
    )
    -
    >
    s
    e
    t
    M
    e
    t
    a
    (
    $
    m
    e
    t
    a
    Setting Response Status Code
    r
    e
    t
    u
    r
    n $
    t
    h
    i
    s
    -
    >
    r
    e
    s
    p
    o
    n
    s
    e
    -
    >
    i
    t
    e
    m
    (
    $
    u
    s
    e
    r
    , n
    e
    w U
    s
    e
    r
    T
    r
    a
    n
    s
    f
    o
    r
    m
    e
    r
    )
    -
    >
    s
    e
    t
    S
    t
    a
    t
    u
    s
    C
    o
    d
    e

    View Slide

  32. TRANSFORMERS
    Easily and consistently transform objects into an array
    Type-cast integers and booleans, include pagination results,
    and nest relationships
    Fractal is the default transformation layer used by Dingo

    View Slide

  33. p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n _
    _
    c
    o
    n
    s
    t
    r
    u
    c
    t
    (
    )
    {
    $
    t
    h
    i
    s
    -
    >
    a
    v
    a
    i
    l
    a
    b
    l
    e
    I
    n
    c
    l
    u
    d
    e
    s = [
    '
    p
    r
    e
    s
    e
    n
    t
    a
    t
    i
    o
    n
    s
    '
    ,
    '
    b
    l
    o
    c
    k
    _
    s
    e
    t
    t
    i
    n
    g
    s
    '
    ,
    ]
    ;
    $
    t
    h
    i
    s
    -
    >
    d
    e
    f
    a
    u
    l
    t
    I
    n
    c
    l
    u
    d
    e
    s = [
    '
    b
    l
    o
    c
    k
    _
    s
    e
    t
    t
    i
    n
    g
    s
    '
    ,
    ]
    ;
    }
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n t
    r
    a
    n
    s
    f
    o
    r
    m
    (
    B
    l
    o
    c
    k $
    b
    l
    o
    c
    k
    )
    {
    r
    e
    t
    u
    r
    n [
    '
    i
    d
    ' =
    > (
    i
    n
    t
    )
    $
    b
    l
    o
    c
    k
    -
    >
    i
    d
    ,
    '
    n
    a
    m
    e
    ' =
    > $
    b
    l
    o
    c
    k
    -
    >
    n
    a
    m
    e
    ,

    View Slide

  34. View Slide

  35. View Slide

  36. FORM REQUEST END ERROR RESPONSES
    Extend the base API form request class
    Implement your own class
    Dingo\Api\Exception\ValidationHttpException should be
    thrown

    View Slide

  37. AUTHENTICATION
    HTTP Basic (Dingo\Api\Auth\Provider\Basic)
    JSON Web Tokens (Dingo\Api\Auth\Provider\JWT)
    OAuth 2.0 (Dingo\Api\Auth\Provider\OAuth2)
    Custom Authentication Providers

    View Slide

  38. DOCUMENTATION
    API Blueprint Documentation
    Annotate API controllers
    Generate documentation using the Artisan command
    But...

    View Slide

  39. DREDD — HTTP API TESTING FRAMEWORK

    View Slide

  40. “ Dredd is a language-agnostic command-line tool for
    validating API documentation written in API Blueprint format
    against its backend implementation. ”
    Dredd reads your API description
    Validates whether API replies with expected responses
    Continuous Integration Support
    Hooks — a glue code for each test setup and teardown
    Use of Gavel.js library
    Do not install dredd manually on Homestead - use a er.sh

    View Slide

  41. HEADERS EXPECTATIONS
    All headers given in example must be present in the
    response
    Only values of headers significant for content negotiation
    are validated
    All other headers values can differ

    View Slide

  42. BODY EXPECTATIONS
    All JSON keys on any level given in the example must be
    present in the response JSON
    Response JSON values must be of the same JSON
    primitive type
    All JSON values can differ
    Arrays can have additional items, type or structure is not
    validated.
    Plain text must match perfectly

    View Slide

  43. PHP Dredd hook handler
    Provides a bridge between the Dredd API Testing Framework
    and PHP environment
    "
    r
    e
    q
    u
    i
    r
    e
    -
    d
    e
    v
    "
    : {
    "
    d
    d
    e
    l
    n
    a
    n
    o
    /
    d
    r
    e
    d
    d
    -
    h
    o
    o
    k
    s
    -
    p
    h
    p
    "
    : "
    ~
    1
    .
    0
    .
    0
    "
    ,
    }

    View Slide

  44. HOOKS USAGE
    Loading db fixtures
    Cleanup a er test step or steps
    Handling authentication and sessions
    Passing data between transactions (saving state from
    responses to stash)
    Modifying request generated from blueprint
    Changing generated expectations
    Setting custom expectations
    Debugging via logging stuff

    View Slide

  45. HOOKS TYPE
    beforeEach
    a erEach
    beforeAll
    a erAll
    before
    a er
    beforeEachValidationHooks
    a erEachValidationHooks

    View Slide

  46. r
    e
    q
    u
    i
    r
    e _
    _
    D
    I
    R
    _
    _ . '
    /
    .
    .
    /
    .
    .
    /
    .
    .
    /
    v
    e
    n
    d
    o
    r
    /
    a
    u
    t
    o
    l
    o
    a
    d
    .
    p
    h
    p
    '
    ;
    $
    a
    p
    p = r
    e
    q
    u
    i
    r
    e _
    _
    D
    I
    R
    _
    _ . '
    /
    .
    .
    /
    .
    .
    /
    .
    .
    /
    b
    o
    o
    t
    s
    t
    r
    a
    p
    /
    a
    p
    p
    .
    p
    h
    p
    '
    ;
    $
    a
    p
    p
    -
    >
    m
    a
    k
    e
    (
    \
    I
    l
    l
    u
    m
    i
    n
    a
    t
    e
    \
    C
    o
    n
    t
    r
    a
    c
    t
    s
    \
    C
    o
    n
    s
    o
    l
    e
    \
    K
    e
    r
    n
    e
    l
    :
    :
    c
    l
    a
    s
    s
    )
    -
    >
    b
    o
    o
    t
    s
    t
    r
    a
    p
    (
    )
    ;
    A
    r
    t
    i
    s
    a
    n
    :
    :
    c
    a
    l
    l
    (
    '
    m
    i
    g
    r
    a
    t
    e
    '
    )
    ;
    $
    u
    s
    e
    r = f
    a
    c
    t
    o
    r
    y
    (
    \
    E
    m
    a
    t
    e
    r
    i
    a
    l
    s
    \
    A
    p
    i
    \
    M
    o
    d
    e
    l
    s
    \
    U
    s
    e
    r
    :
    :
    c
    l
    a
    s
    s
    )
    -
    >
    c
    r
    e
    a
    t
    e
    (
    [
    '
    e
    m
    a
    i
    l
    ' =
    > '
    k
    n
    o
    w
    n
    u
    s
    e
    r
    @
    e
    x
    a
    m
    p
    l
    e
    .
    d
    e
    v
    '
    ]
    )
    ;
    H
    o
    o
    k
    s
    :
    :
    b
    e
    f
    o
    r
    e
    E
    a
    c
    h
    (
    f
    u
    n
    c
    t
    i
    o
    n (
    &
    $
    t
    r
    a
    n
    s
    a
    c
    t
    i
    o
    n
    ) u
    s
    e (
    $
    a
    p
    p
    ) {
    $
    a
    p
    p
    -
    >
    m
    a
    k
    e
    (
    '
    d
    b
    '
    )
    -
    >
    b
    e
    g
    i
    n
    T
    r
    a
    n
    s
    a
    c
    t
    i
    o
    n
    (
    )
    ;
    }
    )
    ;
    H
    o
    o
    k
    s
    :
    :
    a
    f
    t
    e
    r
    E
    a
    c
    h
    (
    f
    u
    n
    c
    t
    i
    o
    n (
    &
    $
    t
    r
    a
    n
    s
    a
    c
    t
    i
    o
    n
    ) u
    s
    e (
    $
    a
    p
    p
    ) {

    View Slide

  47. RUN DREDD
    d
    r
    e
    d
    d d
    o
    c
    u
    m
    e
    n
    t
    a
    t
    i
    o
    n
    .
    a
    p
    i
    b
    h
    t
    t
    p
    :
    /
    /
    l
    o
    c
    a
    l
    h
    o
    s
    t
    :
    8
    0
    0
    1
    -
    -
    s
    e
    r
    v
    e
    r "
    p
    h
    p -
    S 0
    .
    0
    .
    0
    .
    0
    :
    8
    0
    0
    1 -
    t p
    u
    b
    l
    i
    c
    /
    "
    -
    -
    l
    a
    n
    g
    u
    a
    g
    e v
    e
    n
    d
    o
    r
    /
    b
    i
    n
    /
    d
    r
    e
    d
    d
    -
    h
    o
    o
    k
    s
    -
    p
    h
    p
    -
    -
    h
    o
    o
    k
    f
    i
    l
    e
    s t
    e
    s
    t
    s
    /
    d
    r
    e
    d
    d
    /
    h
    o
    o
    k
    s
    /
    h
    o
    o
    k
    f
    i
    l
    e
    .
    p
    h
    p

    View Slide

  48. REPOSITORIES
    "
    r
    e
    q
    u
    i
    r
    e
    "
    : {
    "
    b
    o
    s
    n
    a
    d
    e
    v
    /
    r
    e
    p
    o
    s
    i
    t
    o
    r
    i
    e
    s
    "
    : "
    0
    .
    *
    "
    }
    Container where data access logic is stored
    Hides the details of data access logic from business logic

    View Slide

  49. i
    n
    t
    e
    r
    f
    a
    c
    e R
    e
    p
    o
    s
    i
    t
    o
    r
    y
    I
    n
    t
    e
    r
    f
    a
    c
    e
    {
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n a
    l
    l
    (
    $
    c
    o
    l
    u
    m
    n
    s = a
    r
    r
    a
    y
    (
    '
    *
    '
    )
    )
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n p
    a
    g
    i
    n
    a
    t
    e
    (
    $
    p
    e
    r
    P
    a
    g
    e = 1
    5
    , $
    c
    o
    l
    u
    m
    n
    s = a
    r
    r
    a
    y
    (
    '
    *
    '
    )
    )
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n c
    r
    e
    a
    t
    e
    (
    a
    r
    r
    a
    y $
    d
    a
    t
    a
    )
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n u
    p
    d
    a
    t
    e
    (
    a
    r
    r
    a
    y $
    d
    a
    t
    a
    , $
    i
    d
    )
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n d
    e
    l
    e
    t
    e
    (
    $
    i
    d
    )
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n f
    i
    n
    d
    (
    $
    i
    d
    , $
    c
    o
    l
    u
    m
    n
    s = a
    r
    r
    a
    y
    (
    '
    *
    '
    )
    )
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n f
    i
    n
    d
    B
    y
    (
    $
    f
    i
    e
    l
    d
    , $
    v
    a
    l
    u
    e
    , $
    c
    o
    l
    u
    m
    n
    s = a
    r
    r
    a
    y
    (
    '
    *
    '
    )
    )
    ;
    }

    View Slide

  50. u
    s
    e A
    p
    p
    \
    R
    e
    p
    o
    s
    i
    t
    o
    r
    i
    e
    s
    \
    F
    i
    l
    m
    R
    e
    p
    o
    s
    i
    t
    o
    r
    y a
    s F
    i
    l
    m
    ;
    c
    l
    a
    s
    s F
    i
    l
    m
    s
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r e
    x
    t
    e
    n
    d
    s C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    {
    /
    *
    *
    * @
    v
    a
    r F
    i
    l
    m
    *
    /
    p
    r
    i
    v
    a
    t
    e $
    f
    i
    l
    m
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n _
    _
    c
    o
    n
    s
    t
    r
    u
    c
    t
    (
    F
    i
    l
    m $
    f
    i
    l
    m
    )
    {
    $
    t
    h
    i
    s
    -
    >
    f
    i
    l
    m = $
    f
    i
    l
    m
    ;
    }
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n i
    n
    d
    e
    x
    (
    )
    {
    r
    e
    t
    u
    r
    n \
    R
    e
    s
    p
    o
    n
    s
    e
    :
    :
    j
    s
    o
    n
    (
    $
    t
    h
    i
    s
    -
    >
    f
    i
    l
    m
    -
    >
    a
    l
    l
    (
    )
    )
    ;

    View Slide

  51. Basic actions are just enough for simple querying
    Added CriteriaInterface
    i
    n
    t
    e
    r
    f
    a
    c
    e C
    r
    i
    t
    e
    r
    i
    a
    I
    n
    t
    e
    r
    f
    a
    c
    e
    {
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n s
    k
    i
    p
    C
    r
    i
    t
    e
    r
    i
    a
    (
    $
    s
    t
    a
    t
    u
    s = t
    r
    u
    e
    )
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n g
    e
    t
    C
    r
    i
    t
    e
    r
    i
    a
    (
    )
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n g
    e
    t
    B
    y
    C
    r
    i
    t
    e
    r
    i
    a
    (
    C
    r
    i
    t
    e
    r
    i
    a $
    c
    r
    i
    t
    e
    r
    i
    a
    )
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n p
    u
    s
    h
    C
    r
    i
    t
    e
    r
    i
    a
    (
    C
    r
    i
    t
    e
    r
    i
    a $
    c
    r
    i
    t
    e
    r
    i
    a
    )
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n a
    p
    p
    l
    y
    C
    r
    i
    t
    e
    r
    i
    a
    (
    )
    ;
    }

    View Slide

  52. c
    l
    a
    s
    s L
    e
    n
    g
    t
    h
    O
    v
    e
    r
    T
    w
    o
    H
    o
    u
    r
    s i
    m
    p
    l
    e
    m
    e
    n
    t
    s C
    r
    i
    t
    e
    r
    i
    a
    I
    n
    t
    e
    r
    f
    a
    c
    e
    {
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n a
    p
    p
    l
    y
    (
    $
    m
    o
    d
    e
    l
    , R
    e
    p
    o
    s
    i
    t
    o
    r
    y $
    r
    e
    p
    o
    s
    i
    t
    o
    r
    y
    )
    {
    $
    q
    u
    e
    r
    y = $
    m
    o
    d
    e
    l
    -
    >
    w
    h
    e
    r
    e
    (
    '
    l
    e
    n
    g
    t
    h
    '
    , '
    >
    '
    , 1
    2
    0
    )
    ;
    r
    e
    t
    u
    r
    n $
    q
    u
    e
    r
    y
    ;
    }
    }

    View Slide

  53. u
    s
    e A
    p
    p
    \
    R
    e
    p
    o
    s
    i
    t
    o
    r
    i
    e
    s
    \
    C
    r
    i
    t
    e
    r
    i
    a
    \
    F
    i
    l
    m
    s
    \
    L
    e
    n
    g
    t
    h
    O
    v
    e
    r
    T
    w
    o
    H
    o
    u
    r
    s
    ;
    u
    s
    e A
    p
    p
    \
    R
    e
    p
    o
    s
    i
    t
    o
    r
    i
    e
    s
    \
    F
    i
    l
    m
    R
    e
    p
    o
    s
    i
    t
    o
    r
    y a
    s F
    i
    l
    m
    ;
    c
    l
    a
    s
    s F
    i
    l
    m
    s
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r e
    x
    t
    e
    n
    d
    s C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    {
    /
    *
    *
    * @
    v
    a
    r F
    i
    l
    m
    *
    /
    p
    r
    i
    v
    a
    t
    e $
    f
    i
    l
    m
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n _
    _
    c
    o
    n
    s
    t
    r
    u
    c
    t
    (
    F
    i
    l
    m $
    f
    i
    l
    m
    )
    {
    $
    t
    h
    i
    s
    -
    >
    f
    i
    l
    m = $
    f
    i
    l
    m
    ;
    }
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n i
    n
    d
    e
    x
    (
    )
    {

    View Slide

  54. CORS (CROSS-ORIGIN RESOURCE
    SHARING)
    "
    r
    e
    q
    u
    i
    r
    e
    "
    : {
    "
    b
    a
    r
    r
    y
    v
    d
    h
    /
    l
    a
    r
    a
    v
    e
    l
    -
    c
    o
    r
    s
    "
    : "
    ^
    0
    .
    7
    .
    2
    "
    }
    Allows you to send CORS headers with ACL-style per-url
    configuration.
    Supports Laravel & Lumen

    View Slide

  55. RESOURCES
    -
    -
    -
    Laravel documentation
    Why choose Laravel
    Using Repository

    View Slide