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

F59d2f1ed66b8d9c6ceebea5a748494b?s=128

William Durand

December 12, 2013
Tweet

Transcript

  1. 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
  2. 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 ; } }
  3. 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 " }
  4. 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 >
  5. 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
  6. 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 ) ; } }
  7. 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 >
  8. 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
  9. 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
  10. 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)
  11. 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
  12. 18.

    RMM Level 3 Hypermedia as the Engine of Application State

    (HATEOAS) http://martinfowler.com/articles/richardsonMaturityModel.html
  13. 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
  14. 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 ( ) { } }
  15. 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 " } } }
  16. 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 ] ] >
  17. 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/
  18. 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 * }
  19. 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!)
  20. 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 ( ) { }
  21. 29.
  22. 30.
  23. 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
  24. 33.
  25. 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
  26. 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