$30 off During Our Annual Pro Sale. View Details »

Build Awesome REST APIs With Symfony2 (SymfonyCon)

Build Awesome REST APIs With Symfony2 (SymfonyCon)

Based on concrete examples, you will learn how to build a REST API using Symfony2 and many third-party libraries in an efficient manner. We will dive into each layer including routing, controllers, serialization, versioning, testing, the security layer and even the documentation (this list is not exhaustive). Overall, this talk describes the state of REST in the Symfony2 world.

About us:

* Lukas Kahwe Smith — https://twitter.com/lsmith, https://github.com/lsmith77
* William Durand — https://twitter.com/couac, https://github.com/willdurand

William Durand

December 12, 2013
Tweet

More Decks by William Durand

Other Decks in Programming

Transcript

  1. Build Awesome REST
    APIs With Symfony2
    Lukas Kahwe Smith, William Durand ‑ December 12, 2013

    View Slide

  2. JMSSerializerBundle

    View Slide

  3. In A Nutshell
    Integrates the JMS Serializer library with Symfony2
    Enables (de)serialization of object graphs
    Implements visitor pattern to enable flexibility
    Fully leverage native JSON and XML
    Custom exclusion strategies to determine what to serialize

    View Slide

  4. Usage
    u
    s
    e J
    M
    S
    \
    S
    e
    r
    i
    a
    l
    i
    z
    e
    r
    B
    u
    n
    d
    l
    e
    \
    A
    n
    n
    o
    t
    a
    t
    i
    o
    n a
    s S
    e
    r
    i
    a
    l
    i
    z
    e
    r
    ;
    /
    *
    * @
    S
    e
    r
    i
    a
    l
    i
    z
    e
    r
    \
    X
    m
    l
    R
    o
    o
    t
    (
    "
    r
    e
    s
    p
    o
    n
    s
    e
    "
    ) *
    /
    c
    l
    a
    s
    s M
    y
    R
    e
    s
    p
    o
    n
    s
    e
    {
    /
    *
    * * @
    S
    e
    r
    i
    a
    l
    i
    z
    e
    r
    \
    X
    m
    l
    L
    i
    s
    t
    (
    i
    n
    l
    i
    n
    e
    =
    t
    r
    u
    e
    , e
    n
    t
    r
    y
    =
    "
    a
    r
    t
    i
    c
    l
    e
    "
    ) *
    /
    p
    r
    o
    t
    e
    c
    t
    e
    d $
    a
    r
    t
    i
    c
    l
    e
    s
    ;
    /
    *
    * * @
    S
    e
    r
    i
    a
    l
    i
    z
    e
    r
    \
    X
    m
    l
    A
    t
    t
    r
    i
    b
    u
    t
    e
    (
    ) *
    /
    p
    r
    o
    t
    e
    c
    t
    e
    d $
    p
    a
    g
    e
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n _
    _
    c
    o
    n
    s
    t
    r
    u
    c
    t
    (
    C
    o
    l
    l
    e
    c
    t
    i
    o
    n $
    a
    r
    t
    i
    c
    l
    e
    s
    , $
    p
    a
    g
    e
    )
    {
    $
    t
    h
    i
    s
    -
    >
    a
    r
    t
    i
    c
    l
    e
    s = $
    a
    r
    t
    i
    c
    l
    e
    s
    ;
    $
    t
    h
    i
    s
    -
    >
    p
    a
    g
    e = $
    p
    a
    g
    e
    ;
    }
    }

    View Slide

  5. JSON
    {
    "
    a
    r
    t
    i
    c
    l
    e
    s
    "
    : [
    "
    b
    i
    m
    "
    ,
    "
    b
    a
    m
    "
    ,
    "
    b
    i
    n
    g
    o
    "
    ]
    ,
    "
    p
    a
    g
    e
    "
    : "
    2
    "
    }

    View Slide

  6. XML
    <
    r
    e
    s
    p
    o
    n
    s
    e p
    a
    g
    e
    =
    "
    2
    "
    >
    <
    a
    r
    t
    i
    c
    l
    e
    >
    b
    i
    m
    <
    /
    a
    r
    t
    i
    c
    l
    e
    >
    <
    a
    r
    t
    i
    c
    l
    e
    >
    b
    a
    m
    <
    /
    a
    r
    t
    i
    c
    l
    e
    >
    <
    a
    r
    t
    i
    c
    l
    e
    >
    b
    i
    n
    g
    o
    <
    /
    a
    r
    t
    i
    c
    l
    e
    >
    <
    /
    r
    e
    s
    p
    o
    n
    s
    e
    >

    View Slide

  7. FOSRestBundle

    View Slide

  8. In A Nutshell
    Toolbox of services and listeners to build RESTful APIs
    Generate HTML, XML, JSON from a single action
    Automatic generation of routes from actions
    GET parameter parsing and validation
    Integration with Symfony2 serializer and JMS Serializer
    Integration with SensioFrameworkExtraBundle
    Accept header negotiation
    Request body decoding

    View Slide

  9. Usage
    c
    l
    a
    s
    s R
    e
    s
    t
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    {
    /
    *
    *
    * G
    e
    t t
    h
    e l
    i
    s
    t o
    f a
    r
    t
    i
    c
    l
    e
    s
    * r
    o
    u
    t
    e n
    a
    m
    e
    : l
    i
    i
    p
    _
    h
    e
    l
    l
    o
    _
    r
    e
    s
    t
    _
    g
    e
    t
    _
    a
    r
    t
    i
    c
    l
    e
    s
    * p
    a
    t
    t
    e
    r
    n
    : /
    l
    i
    i
    p
    /
    h
    e
    l
    l
    o
    /
    r
    e
    s
    t
    /
    a
    r
    t
    i
    c
    l
    e
    s
    .
    {
    _
    f
    o
    r
    m
    a
    t
    }
    * h
    t
    t
    p m
    e
    t
    h
    o
    d r
    e
    q
    u
    i
    r
    e
    m
    e
    n
    t
    : G
    E
    T
    *
    * @
    V
    i
    e
    w
    (
    )
    * @
    Q
    u
    e
    r
    y
    P
    a
    r
    a
    m
    (
    n
    a
    m
    e
    =
    "
    p
    a
    g
    e
    "
    , r
    e
    q
    u
    i
    r
    e
    m
    e
    n
    t
    s
    =
    "
    \
    d
    +
    "
    , d
    e
    f
    a
    u
    l
    t
    =
    "
    1
    "
    )
    *
    /
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n g
    e
    t
    A
    r
    t
    i
    c
    l
    e
    s
    A
    c
    t
    i
    o
    n
    (
    $
    p
    a
    g
    e
    )
    {
    $
    a
    r
    t
    i
    c
    l
    e
    s = a
    r
    r
    a
    y
    (
    '
    b
    i
    m
    '
    , '
    b
    a
    m
    '
    , '
    b
    i
    n
    g
    o
    '
    )
    ;
    r
    e
    t
    u
    r
    n n
    e
    w \
    A
    c
    m
    e
    \
    M
    y
    B
    u
    n
    d
    l
    e
    \
    M
    y
    R
    e
    s
    p
    o
    n
    s
    e
    (
    $
    a
    r
    t
    i
    c
    l
    e
    s
    , $
    p
    a
    g
    e
    )
    ;
    }
    }

    View Slide

  10. HTML
    <
    h
    t
    m
    l
    >
    <
    b
    o
    d
    y
    >
    <
    d
    i
    v
    >
    <
    d
    i
    v
    >
    b
    i
    m
    <
    /
    d
    i
    v
    >
    <
    d
    i
    v
    >
    b
    a
    m
    <
    /
    d
    i
    v
    >
    <
    d
    i
    v
    >
    b
    i
    n
    g
    o
    <
    /
    d
    i
    v
    >
    <
    /
    d
    i
    v
    >
    <
    d
    i
    v
    >
    p
    a
    g
    e
    : 2
    <
    /
    d
    i
    v
    >
    <
    /
    b
    o
    d
    y
    >
    <
    /
    h
    t
    m
    l
    >

    View Slide

  11. Media Types and Content
    Type Negotiation
    A short excursion

    View Slide

  12. Unified Resource Identifier
    URIs identify resources
    URIs are format independent
    URI ʺfile extensionsʺ != RESTful

    View Slide

  13. Media Types
    Identifies a representation format
    Custom types use a
    p
    p
    l
    i
    c
    a
    t
    i
    o
    n
    /
    v
    n
    d
    .
    [
    X
    Y
    Z
    ]
    Used inside the A
    c
    c
    e
    p
    t / C
    o
    n
    t
    e
    n
    t
    -
    T
    y
    p
    e headers
    Header Description
    C
    o
    n
    t
    e
    n
    t
    -
    T
    y
    p
    eHTTP message format
    A
    c
    c
    e
    p
    t HTTP response format preference

    View Slide

  14. Content Type Negotiation
    Finding appropriate response format
    No standardized algorithm available
    Apache algorithm is documented
    Also covers encoding (A
    c
    c
    e
    p
    t
    -
    E
    n
    c
    o
    d
    i
    n
    g
    ) and language
    (A
    c
    c
    e
    p
    t
    -
    L
    a
    n
    g
    u
    a
    g
    e
    ) negotiation
    mod_negotiation

    View Slide

  15. Example
    A
    c
    c
    e
    p
    t
    : a
    p
    p
    l
    i
    c
    a
    t
    i
    o
    n
    /
    j
    s
    o
    n
    , a
    p
    p
    l
    i
    c
    a
    t
    i
    o
    n
    /
    x
    m
    l
    ;
    q
    =
    0
    .
    9
    , t
    e
    x
    t
    /
    h
    t
    m
    l
    ;
    q
    =
    0
    .
    8
    ,
    t
    e
    x
    t
    /
    *
    ;
    q
    =
    0
    .
    7
    , *
    /
    *
    ;
    q
    =
    0
    .
    5
    Priority Description
    q
    =
    1
    .
    0 a
    p
    p
    l
    i
    c
    a
    t
    i
    o
    n
    /
    j
    s
    o
    n
    q
    =
    0
    .
    9 a
    p
    p
    l
    i
    c
    a
    t
    i
    o
    n
    /
    x
    m
    l
    q
    =
    0
    .
    8 t
    e
    x
    t
    /
    h
    t
    m
    l
    q
    =
    0
    .
    7 t
    e
    x
    t
    /
    * (ie. any text)
    q
    =
    0
    .
    5 *
    /
    * (ie. any media type)

    View Slide

  16. Example Configuration
    f
    o
    s
    _
    r
    e
    s
    t
    :
    f
    o
    r
    m
    a
    t
    _
    l
    i
    s
    t
    e
    n
    e
    r
    :
    r
    u
    l
    e
    s
    :
    -
    p
    a
    t
    h
    : ^
    /
    p
    r
    i
    o
    r
    i
    t
    i
    e
    s
    : [ h
    t
    m
    l
    , j
    s
    o
    n
    , x
    m
    l ]
    f
    a
    l
    l
    b
    a
    c
    k
    _
    f
    o
    r
    m
    a
    t
    : ~
    p
    r
    e
    f
    e
    r
    _
    e
    x
    t
    e
    n
    s
    i
    o
    n
    : t
    r
    u
    e
    A
    c
    c
    e
    p
    t
    : a
    p
    p
    l
    i
    c
    a
    t
    i
    o
    n
    /
    j
    s
    o
    n
    , a
    p
    p
    l
    i
    c
    a
    t
    i
    o
    n
    /
    x
    m
    l
    ;
    q
    =
    0
    .
    9
    , t
    e
    x
    t
    /
    h
    t
    m
    l
    ;
    q
    =
    0
    .
    8
    ,
    t
    e
    x
    t
    /
    *
    ;
    q
    =
    0
    .
    7
    , *
    /
    *
    ;
    q
    =
    0
    .
    5

    View Slide

  17. BazingaHateoasBundle

    View Slide

  18. RMM Level 3
    Hypermedia as the Engine of Application State (HATEOAS)
    http://martinfowler.com/articles/richardsonMaturityModel.html

    View Slide

  19. BazingaHateoasBundle
    Integrates the Hateoas library with Symfony2
    Leverages the JMS Serializer library
    Relies on the Symfony2 ExpressionLanguage component
    Supports JSON and XML
    Allows to configure links and embedded resources in
    XML, YAML, PHP, or Annotations
    Dynamic relations (relation providers)
    Exclusion strategies

    View Slide

  20. Usage
    u
    s
    e J
    M
    S
    \
    S
    e
    r
    i
    a
    l
    i
    z
    e
    r
    \
    A
    n
    n
    o
    t
    a
    t
    i
    o
    n a
    s S
    e
    r
    i
    a
    l
    i
    z
    e
    r
    ;
    u
    s
    e H
    a
    t
    e
    o
    a
    s
    \
    C
    o
    n
    f
    i
    g
    u
    r
    a
    t
    i
    o
    n
    \
    A
    n
    n
    o
    t
    a
    t
    i
    o
    n a
    s H
    a
    t
    e
    o
    a
    s
    ;
    /
    *
    *
    * @
    S
    e
    r
    i
    a
    l
    i
    z
    e
    r
    \
    X
    m
    l
    R
    o
    o
    t
    (
    "
    u
    s
    e
    r
    "
    )
    *
    * @
    H
    a
    t
    e
    o
    a
    s
    \
    R
    e
    l
    a
    t
    i
    o
    n
    (
    "
    s
    e
    l
    f
    "
    , h
    r
    e
    f = "
    e
    x
    p
    r
    (
    '
    /
    a
    p
    i
    /
    u
    s
    e
    r
    s
    /
    ' ~ o
    b
    j
    e
    c
    t
    .
    g
    e
    t
    I
    d
    (
    )
    )
    "
    )
    *
    /
    c
    l
    a
    s
    s U
    s
    e
    r
    {
    /
    *
    * @
    S
    e
    r
    i
    a
    l
    i
    z
    e
    r
    \
    X
    m
    l
    A
    t
    t
    r
    i
    b
    u
    t
    e *
    /
    p
    r
    i
    v
    a
    t
    e $
    i
    d
    ;
    p
    r
    i
    v
    a
    t
    e $
    f
    i
    r
    s
    t
    N
    a
    m
    e
    ;
    p
    r
    i
    v
    a
    t
    e $
    l
    a
    s
    t
    N
    a
    m
    e
    ;
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n g
    e
    t
    I
    d
    (
    ) {
    }
    }

    View Slide

  21. JSON
    $
    h
    a
    t
    e
    o
    a
    s = H
    a
    t
    e
    o
    a
    s
    B
    u
    i
    l
    d
    e
    r
    :
    :
    c
    r
    e
    a
    t
    e
    (
    )
    -
    >
    b
    u
    i
    l
    d
    (
    )
    ;
    $
    j
    s
    o
    n = $
    h
    a
    t
    e
    o
    a
    s
    -
    >
    s
    e
    r
    i
    a
    l
    i
    z
    e
    (
    n
    e
    w U
    s
    e
    r
    (
    1
    2
    3
    , '
    J
    o
    h
    n
    '
    , '
    D
    o
    e
    '
    )
    , '
    j
    s
    o
    n
    '
    )
    ;
    {
    "
    i
    d
    "
    : 1
    2
    3
    ,
    "
    f
    i
    r
    s
    t
    _
    n
    a
    m
    e
    "
    : "
    J
    o
    h
    n
    "
    ,
    "
    l
    a
    s
    t
    _
    n
    a
    m
    e
    "
    : "
    D
    o
    e
    "
    ,
    "
    _
    l
    i
    n
    k
    s
    "
    : {
    "
    s
    e
    l
    f
    "
    : {
    "
    h
    r
    e
    f
    "
    : "
    /
    a
    p
    i
    /
    u
    s
    e
    r
    s
    /
    1
    2
    3
    "
    }
    }
    }

    View Slide

  22. XML
    $
    h
    a
    t
    e
    o
    a
    s = H
    a
    t
    e
    o
    a
    s
    B
    u
    i
    l
    d
    e
    r
    :
    :
    c
    r
    e
    a
    t
    e
    (
    )
    -
    >
    b
    u
    i
    l
    d
    (
    )
    ;
    $
    x
    m
    l = $
    h
    a
    t
    e
    o
    a
    s
    -
    >
    s
    e
    r
    i
    a
    l
    i
    z
    e
    (
    n
    e
    w U
    s
    e
    r
    (
    1
    2
    3
    , '
    J
    o
    h
    n
    '
    , '
    D
    o
    e
    '
    )
    , '
    x
    m
    l
    '
    )
    ;
    <
    u
    s
    e
    r i
    d
    =
    "
    1
    2
    3
    "
    >
    <
    f
    i
    r
    s
    t
    _
    n
    a
    m
    e
    > <
    /
    f
    i
    r
    s
    t
    _
    n
    a
    m
    e
    >
    <
    l
    a
    s
    t
    _
    n
    a
    m
    e
    > <
    /
    l
    a
    s
    t
    _
    n
    a
    m
    e
    >
    <
    l
    i
    n
    k r
    e
    l
    =
    "
    s
    e
    l
    f
    " h
    r
    e
    f
    =
    "
    /
    a
    p
    i
    /
    u
    s
    e
    r
    s
    /
    1
    2
    3
    "
    /
    >
    <
    /
    u
    s
    e
    r
    >
    <
    !
    [
    C
    D
    A
    T
    A
    [
    J
    o
    h
    n
    ]
    ]
    >
    <
    !
    [
    C
    D
    A
    T
    A
    [
    D
    o
    e
    ]
    ]
    >

    View Slide

  23. TemplatedUriBundle

    View Slide

  24. RFC 6570: URI Template
    A compact sequence of characters for describing a range of
    URIs through variable expansion.
    URIs URI Template
    http://example.com/~fred/ http://example.com/~{username}/
    http://example.com/~mark/

    View Slide

  25. Usage
    d
    e
    m
    o
    _
    r
    o
    u
    t
    e
    :
    p
    a
    t
    t
    e
    r
    n
    : /
    d
    e
    m
    o
    /
    {
    p
    a
    g
    e
    }
    $
    t
    e
    m
    p
    l
    a
    t
    e
    L
    i
    n
    k = $
    t
    h
    i
    s
    -
    >
    g
    e
    t
    (
    '
    h
    a
    u
    t
    e
    l
    o
    o
    k
    .
    r
    o
    u
    t
    e
    r
    .
    t
    e
    m
    p
    l
    a
    t
    e
    '
    )
    -
    >
    g
    e
    n
    e
    r
    a
    t
    e
    (
    '
    d
    e
    m
    o
    _
    r
    o
    u
    t
    e
    '
    , a
    r
    r
    a
    y
    (
    '
    p
    a
    g
    e
    ' =
    > '
    {
    p
    a
    g
    e
    }
    '
    ,
    '
    s
    o
    r
    t
    ' =
    > '
    {
    s
    o
    r
    t
    }
    '
    ,
    '
    f
    i
    l
    t
    e
    r
    ' =
    > a
    r
    r
    a
    y
    (
    '
    {
    f
    i
    l
    t
    e
    r
    }
    '
    )
    ,
    )
    )
    ;
    /
    d
    e
    m
    o
    /
    {
    p
    a
    g
    e
    }
    ?
    {
    &
    s
    o
    r
    t
    }
    {
    &
    f
    i
    l
    t
    e
    r
    %
    5
    B
    %
    5
    D
    *
    }

    View Slide

  26. NelmioApiDocBundle

    View Slide

  27. In A Nutshell
    Generates documentation for your REST APIs
    Gathers information from PHPDoc
    Supports FOSRestBundle, SensioFrameworkExtraBundle,
    JMSSerializerBundle and JMSSecurityExtraBundle
    annotations
    Supports your own annotations
    Allows to add your own parsers
    Sandbox (Killer Feature!)

    View Slide

  28. Usage
    /
    *
    *
    * L
    i
    s
    t a
    l
    l n
    o
    t
    e
    s
    .
    *
    * @
    A
    p
    i
    D
    o
    c
    (
    * r
    e
    s
    o
    u
    r
    c
    e = t
    r
    u
    e
    ,
    * s
    t
    a
    t
    u
    s
    C
    o
    d
    e
    s = { 2
    0
    0 = "
    R
    e
    t
    u
    r
    n
    e
    d w
    h
    e
    n s
    u
    c
    c
    e
    s
    s
    f
    u
    l
    " }
    * )
    * @
    Q
    u
    e
    r
    y
    P
    a
    r
    a
    m
    (
    * n
    a
    m
    e
    =
    "
    o
    f
    f
    s
    e
    t
    "
    , r
    e
    q
    u
    i
    r
    e
    m
    e
    n
    t
    s
    =
    "
    \
    d
    +
    "
    , n
    u
    l
    l
    a
    b
    l
    e
    =
    t
    r
    u
    e
    ,
    * d
    e
    s
    c
    r
    i
    p
    t
    i
    o
    n
    =
    "
    O
    f
    f
    s
    e
    t f
    r
    o
    m w
    h
    i
    c
    h t
    o s
    t
    a
    r
    t l
    i
    s
    t
    i
    n
    g n
    o
    t
    e
    s
    .
    "
    * )
    * @
    Q
    u
    e
    r
    y
    P
    a
    r
    a
    m
    (
    * n
    a
    m
    e
    =
    "
    l
    i
    m
    i
    t
    "
    , r
    e
    q
    u
    i
    r
    e
    m
    e
    n
    t
    s
    =
    "
    \
    d
    +
    "
    , d
    e
    f
    a
    u
    l
    t
    =
    "
    5
    "
    ,
    * d
    e
    s
    c
    r
    i
    p
    t
    i
    o
    n
    =
    "
    H
    o
    w m
    a
    n
    y n
    o
    t
    e
    s t
    o r
    e
    t
    u
    r
    n
    .
    "
    * )
    *
    /
    p
    u
    b
    l
    i
    c f
    u
    n
    c
    t
    i
    o
    n g
    e
    t
    N
    o
    t
    e
    s
    A
    c
    t
    i
    o
    n
    (
    ) {
    }

    View Slide

  29. View Slide

  30. Demo Time

    View Slide

  31. Thank You.
    Questions?

    View Slide

  32. LiipCacheControlBundle
    Response listener to add C
    a
    c
    h
    e
    -
    C
    o
    n
    t
    r
    o
    l headers
    Listener matches the Request path/host/method/attributes
    Varnish helper class to assist in purging/banning content
    Listener to combine reverse proxies with Symfony2 security
    Listener to move flash messages into a cookie

    View Slide

  33. OAuth

    View Slide

  34. OAuth is an open protocol to allow secure authorization
    in a simple and standard method from web, mobile
    and desktop applications.
    It is an authorization framework that enables a third‑party
    application to obtain limited access to an HTTP service.
    http://licpro.williamdurand.fr/security‑slides/#slide83

    View Slide

  35. HWIOAuthBundle
    Client‑side implementation
    Support 20+ different providers
    Supports both OAuth1.0a and OAuth2

    View Slide

  36. FOSOAuthServerBundle
    Server‑side implementation of OAuth2
    Supports Doctrine ORM|ODM, Propel
    Highly configurable
    Thank you for helping us!
    Alan Gabriel Bem
    for OAuth1.0a.
    BazingaOAuthServerBundle

    View Slide