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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size slide

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

    View full-size 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 full-size 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 full-size slide

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

    View full-size slide

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

    View full-size slide

  19. PACKAGES & TOOLS
    Dingo API
    Dredd
    Repositories
    CORS

    View full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size slide

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

    View full-size slide

  35. 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 full-size slide

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

    View full-size slide

  37. DREDD — HTTP API TESTING FRAMEWORK

    View full-size slide

  38. “ 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 full-size slide

  39. 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 full-size slide

  40. 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 full-size slide

  41. 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 full-size slide

  42. 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 full-size slide

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

    View full-size slide

  44. 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 full-size slide

  45. 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 full-size slide

  46. 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 full-size slide

  47. 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 full-size slide

  48. 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 full-size slide

  49. 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 full-size slide

  50. 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 full-size slide

  51. 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 full-size slide

  52. 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 full-size slide

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

    View full-size slide