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

Using VueJS in front of Drupal 8

Brian Ward
November 10, 2015

Using VueJS in front of Drupal 8

Learn how to create beautiful, maintainable and de-coupled applications with Drupal 8.

Source code: https://github.com/briward/examples/tree/master/using-vuejs-in-front-of-drupal-8

More: http://briward.com

Brian Ward

November 10, 2015
Tweet

Other Decks in Programming

Transcript

  1. Using Vue.js in front
    of Drupal 8
    @brian_ward
    1

    View Slide

  2. Hello, i’m Bri(an)
    • Twitter: @brian_ward
    • Drupal: drupal.org/u/briward
    • Website: briward.com
    2 @brian_ward

    View Slide

  3. Yeah, well, that's just, like,
    your opinion, man.

    View Slide

  4. View Slide

  5. It’s finally here(ish)!
    8
    It’s now easier than ever to get off the island.
    5 @brian_ward

    View Slide

  6. “But we already have a
    theme-layer in Drupal?”
    6 @brian_ward
    But we already have a theme-layer in Drupal?

    View Slide

  7. Remember, you don’t have
    to make it fully headless
    @brian_ward
    But we already have a theme-layer in Drupal? 7

    View Slide

  8. Drupal
    system
    Complex user form Interactive feature
    Pages Listings
    Game?!

    View Slide

  9. benefits?
    • Flexibility.
    • Decoupled architecture.
    • (easily) Upgradable/changeable front-end.
    • Dedicated/Focused teams.
    • Happy front-end developers.
    9 @brian_ward
    But we already have a theme-layer in Drupal?
    What are the

    View Slide

  10. So what do we get
    out of the box?
    10 @brian_ward
    So what do we get out of the box?

    View Slide

  11. RESTful Web Services
    RESTful Web Services exposes entities and
    other resources as a RESTful web API.
    Required
    11 @brian_ward
    So what do we get out of the box?

    View Slide

  12. Serialization
    Serialization module provides a service for
    (de)serializing data to/from formats such as
    JSON and XML
    Required
    12 @brian_ward
    So what do we get out of the box?

    View Slide

  13. HAL
    Serializes entities using Hypertext
    Application Language (HAL)
    Optional
    13 @brian_ward
    So what do we get out of the box?

    View Slide

  14. RESTUI
    Provides a user interface for managing REST
    resources.
    Recommended
    14 @brian_ward
    So what do we get out of the box?

    View Slide

  15. 3 ways to create a
    REST API with D8
    15 @brian_ward
    3 ways to create a REST API with D8

    View Slide

  16. 16 @brian_ward
    3 ways to create a REST API with D8
    Using the core RestResources
    Using View REST exports
    Create custom REST resources
    Option #1
    Option #2
    Option #3

    View Slide

  17. Using the core REST
    resources
    /node/{node}
    /entity/block/{block}
    /comment/{comment}
    /entity/comment_type/{comment_type}
    @brian_ward
    17
    Option #1
    Using the core REST resources

    View Slide

  18. Demonstration
    @brian_ward
    18
    Short
    Using the core REST resources

    View Slide

  19. View Slide

  20. Pros & Cons
    @brian_ward
    20
    ✓ Straight out of the box.
    ✓ Requires almost no setup.
    ✓ No custom code necessary.
    - Exposes system information.
    - Absolutely no flexibility.
    - Lacks ability to version.
    - Unable to limit output.
    Using the core REST resources

    View Slide

  21. Using views REST export
    Views is now in core and also comes bundled with REST
    support out of the box.
    21 @brian_ward
    Option #2
    Using views REST export

    View Slide

  22. @brian_ward
    22
    Demonstration
    Short
    Using views REST export

    View Slide

  23. 23 @brian_ward
    Pros & Cons
    ✓ Straight out of the box.
    ✓ Familiar to developers.
    ✓ Manageable within the UI.
    - Returns data with incorrect types.
    - More flexibility, but still limited in
    various areas.
    - Authentication issues.
    Using views REST export

    View Slide

  24. Creating custom REST resources
    Option #3 (recommended)
    Being object-oriented by nature, D8 allows us to extend the base
    ResourceBase class and create our own custom resources. This
    would be my recommendation.
    24 @brian_ward
    Creating custom rest resources

    View Slide

  25. /**

    * Provides a resource to get articles by UUID.

    *

    * @RestResource(

    * id = "articles",

    * label = @Translation("Articles (v1.0)"),

    * uri_paths = {

    * "canonical" = "/api/v1.0/articles/{uuid}"

    * }

    * )

    */

    class ArticleBundleResource extends ResourceBase { }
    25
    Plugin/Rest/Resource/ArticleBundleResource.php @brian_ward

    View Slide

  26. public function getArticle($uuid) {

    $entity = \Drupal::entityManager()->getStorage(‘node')
    ->loadByProperties([

    'uuid' => $uuid,

    'type' => 'article'

    ]);


    return reset($entity);

    }
    26
    Plugin/Rest/Resource/ArticleBundleResource.php @brian_ward

    View Slide

  27. public function get($uuid = NULL) {

    if (Uuid::isValid($uuid)) {

    $entity = $this->getArticle($uuid);

    return new ResourceResponse($this->transform($entity));
    } else {

    return new ResourceResponse([

    ‘http_code’ => 400,
    ‘error' => 100,

    'message' => 'The UUID supplied is invalid.'

    ], 400);

    }

    }
    27
    Plugin/Rest/Resource/ArticleBundleResource.php @brian_ward

    View Slide

  28. private function transform($entity) {

    return [
    'id' => (int) $entity->nid[0]->value,

    'title' => (string) $entity->title[0]->value,
    'published' => (bool) $entity->published[0]->value,

    ];

    }
    28
    Plugin/Rest/Resource/ArticleBundleResource.php @brian_ward

    View Slide

  29. Pros & Cons
    ✓ Provides most flexibility.
    ✓ Transformable output.
    ✓ Easier to manage versions.
    - Requires reasonable
    programming knowledge.
    @brian_ward
    29
    Creating custom rest resources

    View Slide

  30. HATEOAS
    API Theory
    HATEOAS is a constraint of the REST application architecture. In a
    nutshell, it is providing information on how to navigate the site's
    REST resources dynamically by including hypermedia links with
    the responses.
    30 @brian_ward
    HATEOAS

    View Slide

  31. Content negotiation
    To put it simply, this is the mechanism for determining what
    content-type the data will be returned in.
    31 @brian_ward
    HATEOAS

    View Slide

  32. Content negotiation
    32 @brian_ward
    HATEOAS
    ?_format=json
    Basically, this is the mechanism for determining what content-type
    the data will be returned in. Ideally, we would want to use an
    “accept” header.

    View Slide

  33. View Slide

  34. Hypermedia controls
    34
    Provide links to related endpoints so users of your api can easily
    find their way around your data.
    @brian_ward
    HATEOAS

    View Slide

  35. private function transform($entity) {

    return [

    'links' => [

    [

    'rel' => 'self',

    'uri' => '/api/v1.0/articles/'.$entity->uuid[0]->value

    ]

    ]

    ];

    }
    35
    Plugin/Rest/Resource/ArticleBundleResource.php @brian_ward

    View Slide

  36. 'links' => [

    [

    'rel' => 'self',

    'uri' => '/api/v1.0/articles/'.$entity->uuid[0]->value

    ],

    [

    'rel' => ‘article.comments’,

    'uri' => '/api/v1.0/articles/'.$entity->uuid[0]->value.'/comments'

    ]

    ]
    Plugin/Rest/Resource/ArticleBundleResource.php 36 @brian_ward

    View Slide

  37. View Slide

  38. Versioning
    38 @brian_ward
    As Phil Sturgeon says “There are many wrong ways to
    version your API”. Don’t get too caught up about this.

    View Slide

  39. Authentication
    39 @brian_ward
    • Basic auth
    • Cookie
    • oAuth

    View Slide

  40. @brian_ward
    40
    Now that we have created our API, we can play around
    with it on the front-end.
    Now we’re ready

    View Slide

  41. Introducing Vue.js
    Vue.js is a MVVM JavaScript library for building modern web
    interfaces. It provides data-reactive components with a simple and
    flexible API.
    @brian_ward
    41
    Introducing Vue.js

    View Slide

  42. Top trending JS framework on Github.
    @brian_ward
    Introducing Vue.js 42
    First stable version released earlier this month.
    Evan You is also a core developer on the MeteorJS
    project & previously a Google employee.
    Has awesome documentation.

    View Slide

  43. View Slide

  44. View
    new Vue({ el: '#app' })
    Each Vue instance is associated with a DOM element (el).
    44 @brian_ward
    Introducing Vue.js

    View Slide

  45. ViewModel
    45 @brian_ward
    new Vue({ /* options */ })
    • An object that syncs the Model and the View.
    • Every Vue instance is a ViewModel.
    Introducing Vue.js

    View Slide

  46. Model
    new Vue({ data: {} })
    An object that is used as data inside a Vue instance will
    become reactive (Vue instances that are observing our objects
    will be notified of the changes).
    @brian_ward
    46
    Introducing Vue.js

    View Slide

  47. var MyComponent = Vue.extend({})
    Components
    47 @brian_ward
    Components are simply a convenient way to structure and
    organise our applications.
    Optional
    Introducing Vue.js

    View Slide

  48. Browserify & Vueify
    require('./app.vue')
    48 @brian_ward
    Browserify lets you require('modules') in the browser by
    bundling up all of your dependencies.
    Optional
    Introducing Vue.js

    View Slide

  49. this.$http.get(url, callback)
    VueResource
    Using the official Vue-Resource plugin, we can request and
    store our Drupal content as data objects.
    Recommended
    49 @brian_ward
    Introducing Vue.js

    View Slide

  50. router.on(url, callback)
    Director
    A tiny and isomorphic URL router for JavaScript
    Recommended
    50 @brian_ward
    Introducing Vue.js

    View Slide

  51. So where does Drupal
    come in?
    51 @brian_ward
    Introducing Vue.js

    View Slide

  52. View Slide

  53. Great, let’s see that in action!
    Firstly we will need to create our package.json, HTML &
    bootstrap JS files. From there we’ll load in our
    components and interact with our API.
    @brian_ward
    53
    Introducing Vue.js

    View Slide

  54. {

    "main": "./src/app.js",

    "scripts": {

    "watch": "watchify -v -t vueify -e ./src/app.js -o build/build.js"

    },

    "devDependencies": {

    "vueify": "^1.1.5",

    "watchify": "^3.3.1"

    },

    "dependencies": {

    "director": "^1.2.8",

    "vue": "^0.12.9",

    "vue-resource": "^0.1.11"

    }

    }
    package.json 54 @brian_ward

    View Slide
















  55. 55
    index.html @brian_ward

    View Slide

  56. /**

    * Boot up the Vue instance with the VueResource plugin.

    */

    var Vue = require(‘vue')

    Vue.use(require(‘vue-resource’))
    var app = new Vue(require('./app.vue'))
    56
    start.js @brian_ward

    View Slide

  57. /**

    * Wire up the router.

    */

    var Router = require('director').Router

    var router = new Router()


    router.on(‘/articles/:uuid’, function (uuid) {

    app.view = 'article-view'

    app.params.uuid = uuid

    })


    router.init('/')
    57
    start.js @brian_ward

    View Slide


  58. class="view"

    params="{{ params }}"

    v-transition

    transition-mode="out-in">



    58
    app.vue @brian_ward

    View Slide

  59. 
<br/>module.exports = {
<br/>el: '#app',
<br/>data: {
<br/>view: '',
<br/>params: {
<br/>uuid: ''
<br/>}
<br/>},
<br/>components: {
<br/>'article-view': require('./views/article-view.vue')
<br/>}
<br/>}
<br/>
    59
    app.vue @brian_ward

    View Slide









  60. 60
    article-view.vue @brian_ward

    View Slide

  61. 61



    {{ article.title }}

    {{{ article.body }}}




    @brian_ward
    article-view.vue

    View Slide

  62. 
<br/>module.exports = {
<br/>props: ['params'],
<br/>data: function () {
<br/>return {
<br/>article: {}
<br/>}
<br/>},
<br/>ready: function() {<br/>var url = '/api/v1.0/articles/' + uuid + '?_format=json';
<br/>this.$http.get(url, function (article) {
<br/>this.$set('article', article)
<br/>})
<br/>}<br/>}
<br/>
    62 @brian_ward
    article-view.vue

    View Slide

  63. And that’s it.
    By using Drupal 8 and Vue.js we’re able to create a beautiful,
    maintainable and de-coupled application.
    https://github.com/briward/examples
    63 @brian_ward

    View Slide

  64. View Slide

  65. Useful links
    65 @brian_ward
    • http://vuejs.org
    • https://en.wikipedia.org/wiki/Model_View_ViewModel
    • http://browserify.org
    • https://github.com/vuejs/vueify
    • http://vuejs.org/guide/components.html
    • http://www.w3.org/TR/components-intro
    • http://drupal.org/project/restui
    • ...how-to-enable-cors-requests-against-drupal-8/
    • Phil Sturgeon’s book “Build APIs you won’t hate”.

    View Slide