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

Vinna, Reinventing the wheel

Vinna, Reinventing the wheel

Les slides de la présentation de Vinna, un mini-framework MVC web écrit en Java lors de la technozaure du 22/05/2013 à Zenika

Jawher Moussa

May 22, 2013
Tweet

More Decks by Jawher Moussa

Other Decks in Programming

Transcript

  1. Vinna
    Reinventing  the  wheel™
    or
    is
    it
    really
    ?
    Thursday, 23 May, 13

    View Slide

  2. Kesako ?
    Thursday, 23 May, 13

    View Slide

  3. Encore un autre framework web
    Java MVC
    Thursday, 23 May, 13

    View Slide

  4. Thursday, 23 May, 13

    View Slide

  5. Oui. Sérieux !
    Parce que ...
    Thursday, 23 May, 13

    View Slide

  6. Parlons de JSF
    Thursday, 23 May, 13

    View Slide

  7. Standard Java
    Design by Committee
    Thursday, 23 May, 13

    View Slide

  8. Orienté composants
    Thursday, 23 May, 13

    View Slide

  9. Modèle de dev: on accède
    à des pages qui font des
    callbacks vers du Java
    Thursday, 23 May, 13

    View Slide

  10. Framework conçu
    pour être stateful
    Thursday, 23 May, 13

    View Slide

  11. C’est pas mauvais en soi, mais
    y’a des cas où on veut du
    stateless: site web public par
    exemple
    Thursday, 23 May, 13

    View Slide

  12. Cycle de vie complexe
    Thursday, 23 May, 13

    View Slide

  13. Ça impacte les
    performances
    Thursday, 23 May, 13

    View Slide

  14. (lancement de
    free mobile)
    Thursday, 23 May, 13

    View Slide

  15. Les créateurs de JSF 1 avaient
    complètement oublié le verbe
    GET ainsi que la possibilité de
    répéter un bloc HTML
    LOL
    Thursday, 23 May, 13

    View Slide

  16. Jeux de composants
    “prêt à porter”:
    Primefaces, Richfaces, etc.
    Thursday, 23 May, 13

    View Slide

  17. Pratique juste pour du
    backoffice/prototypage
    Thursday, 23 May, 13

    View Slide

  18. Besoin de contrôler
    finement son HTML/CSS
    dans un vrai site/appli
    Thursday, 23 May, 13

    View Slide

  19. Modèle de dev un peu
    tordu car piloté par la vue
    Thursday, 23 May, 13

    View Slide

  20. Impossible de faire des URLs
    propres (faut que ça pointe vers
    un fichier de page) sans url
    rewriting
    LOL
    x
    2
    Thursday, 23 May, 13

    View Slide

  21. Et Wicket alors ?
    D
    ésolé
    N
    ico
    !
    Thursday, 23 May, 13

    View Slide

  22. Orienté composants,
    Swing-like
    Thursday, 23 May, 13

    View Slide

  23. Très puissant
    une fois maitrisé
    Thursday, 23 May, 13

    View Slide

  24. Les vues c’est juste du
    *, on contrôle
    tout avec du Java
    *: Avec quand même des ids pour binder
    Thursday, 23 May, 13

    View Slide

  25. Mais idem, conçu
    pour être stateful
    Thursday, 23 May, 13

    View Slide

  26. On peut faire du stateless,
    mais on passe notre temps à
    se battre contre le framework
    Thursday, 23 May, 13

    View Slide

  27. Très facile de finir avec
    toute sa base de
    données dans la session
    Thursday, 23 May, 13

    View Slide

  28. Verbeux
    Complexe
    Thursday, 23 May, 13

    View Slide

  29. Mais 10 fois mieux
    que JSF quand même
    Thursday, 23 May, 13

    View Slide

  30. Struts 2
    Thursday, 23 May, 13

    View Slide

  31. Thursday, 23 May, 13

    View Slide

  32. Trop de config:
    interceptors
    Thursday, 23 May, 13

    View Slide

  33. Contrôleurs ne sont pas
    des POJO.
    Enfin si mais non ...
    Thursday, 23 May, 13

    View Slide

  34. e.g.
    ParamAware, etc.
    Thursday, 23 May, 13

    View Slide

  35. Lourd: e.g. un setter par
    paramètre à récupérer +
    configurer l’interceptor qu’il faut
    Thursday, 23 May, 13

    View Slide

  36. Pas de façon “portable”
    pour passer le modèle à
    la vue
    Thursday, 23 May, 13

    View Slide

  37. Les taglibs qui
    réinventent HTML
    Thursday, 23 May, 13

    View Slide

  38. Et puis y’a Struts
    dans le nom ...
    Thursday, 23 May, 13

    View Slide

  39. Spring MVC
    Thursday, 23 May, 13

    View Slide

  40. Un pas dans la
    bonne direction
    Thursday, 23 May, 13

    View Slide

  41. Mais trop
    flexible
    Thursday, 23 May, 13

    View Slide

  42. Trop de manières
    différentes de faire la
    même chose
    Thursday, 23 May, 13

    View Slide

  43. On peut retourner void, String,
    ModelAndView, View, prendre un
    OutputStream ou
    ServletResponse, etc.
    Thursday, 23 May, 13

    View Slide

  44. Difficile à mettre en place
    dès que
    developpers.count()  >  1
    Thursday, 23 May, 13

    View Slide

  45. GWT
    Thursday, 23 May, 13

    View Slide

  46. Ça résout pas du tout la
    même problématique
    Thursday, 23 May, 13

    View Slide

  47. Le JS n’est pas la
    réponse à tout (42)
    Thursday, 23 May, 13

    View Slide

  48. e.g. Twitter
    Thursday, 23 May, 13

    View Slide

  49. En plus d’autres problèmes
    (verbosité, taille du code
    généré, etc.)
    Thursday, 23 May, 13

    View Slide

  50. Et les autres
    frameworks JS ?
    Thursday, 23 May, 13

    View Slide

  51. Idem que pour
    GWT
    Thursday, 23 May, 13

    View Slide

  52. Grails
    Thursday, 23 May, 13

    View Slide

  53. est là ou pas ?
    Thursday, 23 May, 13

    View Slide

  54. Non
    sérieusement
    Thursday, 23 May, 13

    View Slide

  55. Magie
    Thursday, 23 May, 13

    View Slide

  56. Magie noire
    Thursday, 23 May, 13

    View Slide

  57. Perfs
    Thursday, 23 May, 13

    View Slide

  58. Full-stack
    Thursday, 23 May, 13

    View Slide

  59. Play ?
    Thursday, 23 May, 13

    View Slide

  60. Les idées sont
    très bonnes
    Thursday, 23 May, 13

    View Slide

  61. C’est pas révolutionnaire
    non plus: c’est Rails sur
    JVM
    Thursday, 23 May, 13

    View Slide

  62. Mais
    l’exécution ...
    Thursday, 23 May, 13

    View Slide

  63. Contrôleurs
    statiques (TU, DI)
    Thursday, 23 May, 13

    View Slide

  64. Magie (manipulation
    du bytecode)
    Thursday, 23 May, 13

    View Slide

  65. Pas basé sur les
    servlets ... dudes,
    really ?
    Thursday, 23 May, 13

    View Slide

  66. Non blocking, real time,
    bla bla bla, et pourtant,
    les perfs ne suivent pas
    Thursday, 23 May, 13

    View Slide

  67. Play 2
    Thursday, 23 May, 13

    View Slide

  68. LOL
    Thursday, 23 May, 13

    View Slide

  69. D’où Vinna
    Thursday, 23 May, 13

    View Slide

  70. On pense vraiment que
    le super framework
    MVC/Action sur JVM
    n’existe pas encore
    Thursday, 23 May, 13

    View Slide

  71. Ainsi que
    Thursday, 23 May, 13

    View Slide

  72. Vinna = Travail (en islandais)
    Et gagner (en suédois)
    Thursday, 23 May, 13

    View Slide

  73. Les 4
    commandements
    Thursday, 23 May, 13

    View Slide

  74. 1. de la magie
    tu ne feras point
    Thursday, 23 May, 13

    View Slide

  75. 2. Simple tu
    seras
    Thursday, 23 May, 13

    View Slide

  76. 3. Les standards
    tu ré-utiliseras*
    *: On aime bien ré-inventer la roue mais faut pas abuser non plus
    Thursday, 23 May, 13

    View Slide

  77. Features
    Thursday, 23 May, 13

    View Slide

  78. MVC: Java first
    Thursday, 23 May, 13

    View Slide

  79. Centraliser la
    déclaration des routes
    Thursday, 23 May, 13

    View Slide

  80. Stateless
    Thursday, 23 May, 13

    View Slide

  81. Basé sur les
    servlets
    Thursday, 23 May, 13

    View Slide

  82. Validation (avec
    support de la JSR 303)
    Thursday, 23 May, 13

    View Slide

  83. Intégration avec
    Spring
    Thursday, 23 May, 13

    View Slide

  84. REST
    Thursday, 23 May, 13

    View Slide

  85. G¼stï¢on du
    i18n
    Thursday, 23 May, 13

    View Slide

  86. Facile à étendre
    Thursday, 23 May, 13

    View Slide

  87. Templating: JSP (beurk)
    et Liquirods (whoa)
    Thursday, 23 May, 13

    View Slide

  88. Etc. (upload,
    cookies, session, ...)
    Thursday, 23 May, 13

    View Slide

  89. Quickstart
    Thursday, 23 May, 13

    View Slide

  90. Créer projet
    web maven
    Thursday, 23 May, 13

    View Slide

  91. Ou utiliser les
    archetypes Vinna
    Thursday, 23 May, 13

    View Slide

  92. 2 modes: déclaratif
    et programmatique
    Thursday, 23 May, 13

    View Slide

  93. Déclaratif
    Thursday, 23 May, 13

    View Slide

  94. Structure
    Contrôleur
    Déclaration
    des  routes
    Déclaration
    du  filtre  Vinna
    Thursday, 23 May, 13

    View Slide

  95. web.xml
           
                   vinnaFilter
                   vinna.VinnaFilter
                   
                           base-­‐package
                           vinna
                   
           
           
                 vinnaFilter
                 /*
           
    Thursday, 23 May, 13

    View Slide

  96. Déclaration des routes
    GET  /  HelloController.index()
    GET  /hello/{name}  HelloController.sayHello({name},  {req.param.ohai})
    Thursday, 23 May, 13

    View Slide

  97. Ze contrôleur
    package  vinna.controllers;
    import  vinna.response.Response;
    import  vinna.response.StringResponse;
    public  class  HelloController  {
           public  Response  index()  {
                   return  new  StringResponse("Go  to  /hello/{your  name}  for  a  free  hug  !");
           }
           public  Response  sayHello(String  name,  String  ohai)  {
                   return  new  StringResponse(String.format("%s  %s  !",  (ohai  ==  null  ?  "Ohai"  :  ohai),  name));
           }
    }
    Thursday, 23 May, 13

    View Slide

  98. Et c’est tout !
    mvn jetty:run
    Thursday, 23 May, 13

    View Slide

  99. Programmatique
    Thursday, 23 May, 13

    View Slide

  100. Structure
    Déclaration
    des  routes
    Déclaration
    du  filtre  Vinna
    Contrôleur
    Thursday, 23 May, 13

    View Slide

  101. web.xml
           
                   vinnaFilter
                   vinna.VinnaFilter
                   
                           application-­‐class
                           vinna.VinnApp
                   
           
           
                 vinnaFilter
                 /*
           
    Thursday, 23 May, 13

    View Slide

  102. Déclaration des routes
    package  vinna;
    import  java.util.Map;
    import  vinna.controllers.HelloController;
    import  vinna.Vinna;
    public  class  VinnApp  extends  Vinna  {
           @Override
           protected  void  routes(Map  config)  {
                   get("/").withController(HelloController.class).index();
                   get("/hello/{name}").withController(HelloController.class).sayHello(
                                   param("name").asString(),
                                   req.param("ohai").asString()
                   );
           }
    }
    Thursday, 23 May, 13

    View Slide

  103. Ze même contrôleur
    package  vinna.controllers;
    import  vinna.response.Response;
    import  vinna.response.StringResponse;
    public  class  HelloController  {
           public  Response  index()  {
                   return  new  StringResponse("Go  to  /hello/{your  name}  for  a  free  hug  !");
           }
           public  Response  sayHello(String  name,  String  ohai)  {
                   return  new  StringResponse(String.format("%s  %s  !",  (ohai  ==  null  ?  "Ohai"  :  ohai),  name));
           }
    }
    Thursday, 23 May, 13

    View Slide

  104. Les réponses
    Thursday, 23 May, 13

    View Slide

  105. Une simple interface
    package  vinna.response;
    import  vinna.http.VinnaRequestWrapper;
    import  vinna.http.VinnaResponseWrapper;
    import  javax.servlet.ServletException;
    import  java.io.IOException;
    public  interface  Response  {
           public  void  execute(VinnaRequestWrapper  request,
                                                   VinnaResponseWrapper  response)
                           throws  IOException,  ServletException;
    }
    Thursday, 23 May, 13

    View Slide

  106. Vinna fournit un builder
    ResponseBuilder.withStatus(404)
           .addHeader("X-­‐Where",  "Zlocalhost")
           .cookie(new  Cookie("zcookie",  "zvalue"))
           .etag("24674U75I8673")
           .type("application/technozaure");
    Thursday, 23 May, 13

    View Slide

  107. Et d’autres
    implems
    Thursday, 23 May, 13

    View Slide

  108. Success.*
    •  Success.created()
    •  Success.ok()
    •  Success.noContent()
    •  ...
    Thursday, 23 May, 13

    View Slide

  109. ClientError.*
    •  ClientError.notFound()
    •  ClientError.badRequest()
    •  ...
    Thursday, 23 May, 13

    View Slide

  110. ServerError.*
    •  ServerError.internalError()
    •  ServerError.unavailable()
    •  ...
    Thursday, 23 May, 13

    View Slide

  111. Redirect.*
    •  Redirect.moved()
    •  Redirect.permanently()
    •  ...
    Thursday, 23 May, 13

    View Slide

  112. Forward
    Pour  renvoyer  une  JSP  par  exemple
    Thursday, 23 May, 13

    View Slide

  113. LiquidrodsView
    Pour  renvoyer  une  vue  liquidrods
    Thursday, 23 May, 13

    View Slide

  114. Liquidrods
    Thursday, 23 May, 13

    View Slide

  115. Langage de templating
    inspirée de Mustache/
    Handlebars et de Liquid/Jinja2
    Thursday, 23 May, 13

    View Slide

  116. exemple: base.html


           
           Todorods
           



           {%  block  content  %}
           {%  end  %}



    Thursday, 23 May, 13

    View Slide

  117. exemple : list.html
    {%  extends  base.html  %}
    {%  block  content  %}
    TODO  list

           
           
                   Title
                   Description
           
           
           
           {%  for  todos  %}
           
                   {{  title  }}
                   {{  description  }}
           
           {%  end  %}
           


    Create
    {%  end  %}
    Thursday, 23 May, 13

    View Slide

  118. exemple : create.html
    {%  extends  base.html  %}
    {%  block  content  %}
    TODO

           Create  a  new  todo:
           
                   
                           Title
                           
                                   
                                   {%  if  firstErrors.title  %}
                                   {{firstErrors.title}}
                                   {%  end  %}
                           
                   
                   ...
                   
                           
                                   Create
                           
                   
           

    {%  end  %}
    Thursday, 23 May, 13

    View Slide

  119. Et bien plus de
    fonctionnalités, mais on
    a plus le temps là ...
    Thursday, 23 May, 13

    View Slide

  120. Routes
    Thursday, 23 May, 13

    View Slide

  121. Exemples (déclaratif)
    GET    /css/bootstrap.min.css  pass
    GET    /**/*.js  pass
    GET    /        TodoController.list()
    GET    /new  TodoController.create()
    POST  /new  TodoController.create({req.param.title},  {req.param.debug})
    req.param.debug:  true|false
    GET  /api/{id}  ApiTodoController.show({id})
           id:  \d+
    POST  /api  ApiTodoController.create(JacksonArgument)
    GET  /create  TodoController.create(TodoParameter)
    GET  /resource  Controller.get({req.header.ETag})
    Thursday, 23 May, 13

    View Slide

  122. Exemples (programmatique)
    get("/css/bootstrap.min.css").pass();
    get("/").withController(TodoController.class).list();
    get("/new").withController(TodoController.class).create();
    post("/new").withController(TodoController.class).create(
                   req.param("title").asString(),  
    req.param("description").asString());
    get("/api").withController(ApiTodoController.class).list();
    get("/api/{id:  \\d+}").withController(ApiTodoController.class)
                   .show(param("id").asLong());
    post("/api").withController(ApiTodoController.class)
                   .create(custom(JacksonArgument.class).asT());
    get("/create").withController(TodoController.class).
                   create(custom(TodoParameter.class).asTodo());
    Thursday, 23 May, 13

    View Slide

  123. Validation
    Thursday, 23 May, 13

    View Slide

  124. De base
    Validation  validation  =  new  Validation();
    validation.required(title,  "title").required(description,  "description");
    if  (validation.hasErrors())  {
           return  new  CreateView(title,  description,  validation);
    }
    Thursday, 23 May, 13

    View Slide

  125. Avec JSR-303
    public  class  Todo  {
           private  Long  id;
           @NotNull
           @Size(min  =  2,  max  =  128)
           private  String  title;
           @NotNull
           @Size(max  =  512)
           private  String  description;
    :
    :
    Validation  validation  =  new  Validation().validate(todo);
    if  (!validation.hasErrors())  {
           :
           :
    }
    Thursday, 23 May, 13

    View Slide

  126. Road map
    Thursday, 23 May, 13

    View Slide

  127. Reverse routing
    Thursday, 23 May, 13

    View Slide

  128. Compatibilité
    Java 6
    Thursday, 23 May, 13

    View Slide

  129. Un vrai parseur
    de routes
    Thursday, 23 May, 13

    View Slide

  130. Négociation de
    contenu
    Thursday, 23 May, 13

    View Slide

  131. Quelques APIs en pleine crise
    d’adolescence (validation,
    conversion des arguments,
    syntaxe des routes, etc.)
    Thursday, 23 May, 13

    View Slide

  132. That’s all folks
    Et merci !
    Thursday, 23 May, 13

    View Slide

  133. Projet sur GitHub
    github.com/jawher/vinna
    • haklop, aka Éric
    • lpereir4, aka Lucien
    • jawher, aka Jawher
    Starring
    Thursday, 23 May, 13

    View Slide