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. Build Awesome REST APIs With Symfony2 Lukas Kahwe Smith, William

    Durand ‑ December 12, 2013
  2. JMSSerializerBundle

  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
  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 ; } }
  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 " }
  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 >
  7. FOSRestBundle

  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
  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 ) ; } }
  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 >
  11. Media Types and Content Type Negotiation A short excursion

  12. Unified Resource Identifier URIs identify resources URIs are format independent

    URI ʺfile extensionsʺ != RESTful
  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
  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
  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)
  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
  17. BazingaHateoasBundle

  18. RMM Level 3 Hypermedia as the Engine of Application State

    (HATEOAS) http://martinfowler.com/articles/richardsonMaturityModel.html
  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
  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 ( ) { } }
  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 " } } }
  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 ] ] >
  23. TemplatedUriBundle

  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/
  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 * }
  26. NelmioApiDocBundle

  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!)
  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 ( ) { }
  29. None
  30. Demo Time

  31. Thank You. Questions?

  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
  33. OAuth

  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
  35. HWIOAuthBundle Client‑side implementation Support 20+ different providers Supports both OAuth1.0a

    and OAuth2
  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