diff --git a/rest_example/config/install/node.type.rest_example_test.yml b/rest_example/config/install/node.type.rest_example_test.yml
new file mode 100644
index 0000000..93090de
--- /dev/null
+++ b/rest_example/config/install/node.type.rest_example_test.yml
@@ -0,0 +1,12 @@
+# Imports a new node type that we use for testing REST. The content that we
+# create, read, update and delete will be of this type.
+uuid: 193dbae8-6c06-48bd-b70c-123356112304
+langcode: en
+status: true
+name: 'Rest Example Test'
+type: rest_example_test
+description: 'This content is created through the REST API'
+help: ''
+new_revision: false
+preview_mode: 0
+display_submitted: false
diff --git a/rest_example/config/install/views.view.rest_service.yml b/rest_example/config/install/views.view.rest_service.yml
new file mode 100644
index 0000000..9125d46
--- /dev/null
+++ b/rest_example/config/install/views.view.rest_service.yml
@@ -0,0 +1,453 @@
+# This View is used to collect the all the relevant nodes from the system, of
+# the type 'rest_example_test', and print them as json, so that we can use it
+# in or REST module.
+uuid: a076bbde-d372-404b-ac0a-1001e0d5dbb5
+langcode: en
+status: true
+dependencies:
+  config:
+    - node.type.rest_example_test
+  module:
+    - node
+    - rest
+    - user
+id: rest_service
+label: 'REST Service'
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: none
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: full
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          tags:
+            previous: '‹ previous'
+            next: 'next ›'
+            first: '« first'
+            last: 'last »'
+          quantity: 9
+      style:
+        type: serializer
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        nid:
+          id: nid
+          table: node_field_data
+          field: nid
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: number_unformatted
+          settings:
+            thousand_separator: ''
+            prefix_suffix: 0
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: node
+          entity_field: nid
+          plugin_id: field
+        type:
+          id: type
+          table: node_field_data
+          field: type
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: target_id
+          type: entity_reference_label
+          settings:
+            link: false
+          group_column: target_id
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: node
+          entity_field: type
+          plugin_id: field
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: false
+            ellipsis: false
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: string
+          settings:
+            link_to_entity: false
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: node
+          entity_field: title
+          plugin_id: field
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          date_format: fallback
+          custom_date_format: ''
+          timezone: ''
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+      filters:
+        type:
+          id: type
+          table: node_field_data
+          field: type
+          value:
+            rest_example_test: rest_example_test
+          entity_type: node
+          entity_field: type
+          plugin_id: bundle
+      sorts:
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          order: DESC
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exposed: false
+          expose:
+            label: ''
+          granularity: second
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments:
+        nid:
+          id: nid
+          table: node_field_data
+          field: nid
+          relationship: none
+          group_type: group
+          admin_label: 'Node ID'
+          default_action: ignore
+          exception:
+            value: all
+            title_enable: false
+            title: All
+          title_enable: false
+          title: ''
+          default_argument_type: fixed
+          default_argument_options:
+            argument: ''
+          default_argument_skip_url: false
+          summary_options:
+            base_path: ''
+            count: true
+            items_per_page: 25
+            override: false
+          summary:
+            sort_order: asc
+            number_of_records: 0
+            format: default_summary
+          specify_validation: true
+          validate:
+            type: 'entity:node'
+            fail: 'not found'
+          validate_options:
+            bundles:
+              rest_example_test: rest_example_test
+            operation: view
+            multiple: '0'
+            access: 0
+          break_phrase: false
+          not: false
+          entity_type: node
+          entity_field: nid
+          plugin_id: numeric
+      display_extenders: {  }
+      title: 'REST Service'
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - request_format
+        - url
+        - url.query_args
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
+  rest_export_1:
+    display_plugin: rest_export
+    id: rest_export_1
+    display_title: 'REST export'
+    position: 1
+    display_options:
+      display_extenders: {  }
+      path: rest/node
+      pager:
+        type: none
+        options:
+          offset: 0
+      style:
+        type: serializer
+        options:
+          grouping: {  }
+          uses_fields: false
+          formats: {  }
+      row:
+        type: data_field
+        options:
+          field_options:
+            title:
+              alias: ''
+              raw_output: false
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - request_format
+        - url
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
diff --git a/rest_example/rest_example.info.yml b/rest_example/rest_example.info.yml
new file mode 100644
index 0000000..b2ea60f
--- /dev/null
+++ b/rest_example/rest_example.info.yml
@@ -0,0 +1,11 @@
+name: REST Example
+type: module
+description: An example outlining how a module can use the RESTful Web Services to communicate with another Drupal instance.
+package: Example modules
+core: 8.x
+dependencies:
+  - rest
+  - basic_auth
+  - hal
+  - views
+  - examples
diff --git a/rest_example/rest_example.links.action.yml b/rest_example/rest_example.links.action.yml
new file mode 100644
index 0000000..3e8805d
--- /dev/null
+++ b/rest_example/rest_example.links.action.yml
@@ -0,0 +1,5 @@
+rest_example.create_node:
+  route_name: rest_example.client_actions_create
+  title: 'Create node'
+  appears_on:
+    - rest_example.client_actions_index
\ No newline at end of file
diff --git a/rest_example/rest_example.links.menu.yml b/rest_example/rest_example.links.menu.yml
new file mode 100644
index 0000000..63b42cf
--- /dev/null
+++ b/rest_example/rest_example.links.menu.yml
@@ -0,0 +1,16 @@
+# This file contains entries that will appear in the "Tool" menu.
+
+# Creates a link that points to the page where we can setup the REST client, so
+# that it will know where the server resides, and how to authenticate.
+rest_example.settings:
+  title: 'REST Example: Client Settings'
+  description: 'Callback for REST client settings form.'
+  route_name: rest_example.client_settings
+
+# This link points to the page where all the magic happens: The display of the
+# nodes on the remote server, and from where we can create, edit and delete them
+# too.
+rest_example.actions:
+  title: 'REST Example: Client Actions'
+  description: 'Callback for REST client action form.'
+  route_name: rest_example.client_actions_index
\ No newline at end of file
diff --git a/rest_example/rest_example.module b/rest_example/rest_example.module
new file mode 100644
index 0000000..3ef60eb
--- /dev/null
+++ b/rest_example/rest_example.module
@@ -0,0 +1,61 @@
+<?php
+/**
+ * @file
+ * This is a demonstration of how to the REST service in Drupal works.
+ */
+
+/**
+ * @defgroup rest_example Example: REST
+ * @ingroup examples
+ * @{
+ * This module will give you a brief demonstration of how the REST service
+ * works.
+ *
+ * This example uses nodes, because they works out of the box. But any entity
+ * could be used.
+ *
+ * To fullfill a demo, we'll need a server site, containing the nodes, and a
+ * client, that sends requests to the server. The same site can very well act
+ * as both client and server.
+ *
+ * First thing you want to do, is visit 'examples/rest_client_settings' and setup
+ * what website you want to interact with. To avoid complications, and minimize
+ * the chance of failure, I'll sugest that you start using the same site as both
+ * server and client, using the user 1 credentials. And when you have gotten the
+ * feel of how things works, try to use two seperate sites, and maybe another
+ * user. Please note that you need to install this module on both client and
+ * server site.
+ *
+ * Next thing you want is to go to 'examples/rest_client_actions'. This page
+ * contains a table where all the remote nodes, of the type rest_example_test,
+ * will be displayed. At first there might not be any.
+ *
+ * From the same page you can create, edit and delete nodes on the remote site.
+ *
+ * The server site actually only uses the View (rest_serice) and the node type
+ * (rest_example_test), imported upon installatin of this module. The rest of
+ * the functionallity comes from Drupal Core modules, like 'rest', 'basic_auth'
+ * and 'hal'.
+ *
+ * The client part of the site uses:
+ *
+ *  - @see \Drupal\rest_example\Controller\RestExampleClientController::indexAction()
+ *    Builds the list of nodes on the remote server.
+ *
+ *  - @see \Drupal\rest_example\Form\RestExampleClientSettings
+ *    A form that can creates/edits nodes.
+ *
+ *  - @see \Drupal\rest_example\Form\RestExampleClientSettings
+ *    A form used to confirm the deletion of the node.
+ *
+ *  - @see \Drupal\rest_example\Form\RestExampleClientSettings
+ *    A form wher you setup what site you want to interact with.
+ *
+ *  - @see \Drupal\rest_example\RestExampleClientCalls
+ *    This class handles all the calls to the remote site, and returns the
+ *    response back, to be processed by the requesting method.
+ */
+
+/**
+ * @} End of "defgroup rest_example".
+ */
\ No newline at end of file
diff --git a/rest_example/rest_example.routing.yml b/rest_example/rest_example.routing.yml
new file mode 100644
index 0000000..4ce039d
--- /dev/null
+++ b/rest_example/rest_example.routing.yml
@@ -0,0 +1,46 @@
+# These routes are tells Drupal where to find the content/actions for each URL.
+
+# The client setup page.
+rest_example.client_settings:
+  path: 'examples/rest_client_settings'
+  defaults:
+    _title: 'Connect to a remote Drupal site'
+    _form: '\Drupal\rest_example\Form\RestExampleClientSettings'
+  requirements:
+    _access: 'TRUE'
+
+# Listing of all the remote nodes, of the type rest_example_test.
+rest_example.client_actions_index:
+  path: 'examples/rest_client_actions'
+  defaults:
+    _title: 'Nodes on the remote Drupal server'
+    _controller: '\Drupal\rest_example\Controller\RestExampleClientController::indexAction'
+  requirements:
+    _access: 'TRUE'
+
+# Create a new node on the remote server.
+rest_example.client_actions_create:
+  path: 'examples/rest_client_actions/create'
+  defaults:
+    _title: 'Create node on remote Drupal server'
+    _form: '\Drupal\rest_example\Form\RestExampleClientEdit'
+  requirements:
+    _access: 'TRUE'
+
+# Edit a node on the remote server.
+rest_example.client_actions_edit:
+  path: 'examples/rest_client_actions/edit/{id}'
+  defaults:
+    _title: 'Edit node on remote Drupal server'
+    _form: '\Drupal\rest_example\Form\RestExampleClientEdit'
+  requirements:
+    _access: 'TRUE'
+
+# Delete a node on the remote server.
+rest_example.client_actions_delete:
+  path: 'examples/rest_client_actions/delete/{id}'
+  defaults:
+    _title: 'Delete node on remote Drupal server'
+    _form: '\Drupal\rest_example\Form\RestExampleClientDelete'
+  requirements:
+    _access: 'TRUE'
\ No newline at end of file
diff --git a/rest_example/src/Controller/RestExampleClientController.php b/rest_example/src/Controller/RestExampleClientController.php
new file mode 100644
index 0000000..13c8bba
--- /dev/null
+++ b/rest_example/src/Controller/RestExampleClientController.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\rest_example\Controller\RestExampleClientController.
+ */
+
+namespace Drupal\rest_example\Controller;
+
+use Drupal\Core\Controller\ControllerBase;
+use Drupal\rest_example\RestExampleClientCalls;
+use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Core\Url;
+
+/**
+ * Controller routines for rest example routes.
+ *
+ * @ingroup rest_example
+ */
+class RestExampleClientController extends ControllerBase {
+
+  /**
+   * Retreive a list of all nodes available on the remote site.
+   *
+   * Building the list as a table, by calling the RestExampleClientCalls::index()
+   * and builds the list from the response of that.
+   */
+  public function indexAction() {
+
+    $build = array();
+
+    $client = new RestExampleClientCalls(\Drupal::httpClient());
+    $nodes = $client->index();
+
+    $build['intro'] = array(
+      '#markup' => $this->t('This is a list of nodes, of type <em>Rest Example Test</em>, on the remote server. From here you can create new node, edit and delete existing ones.'),
+    );
+
+    $build['node_table'] = array(
+      '#type' => 'table',
+      '#header' => array($this->t('Title'), $this->t('Type'), $this->t('Created'), $this->t('Edit'), $this->t('Delete')),
+      '#empty' => t('There are no items on the remote system yet'),
+    );
+
+    if (!empty($nodes)) {
+      foreach ($nodes as $delta => $node) {
+        $build['node_table'][$delta]['title']['#markup'] = SafeMarkup::checkPlain($node['title']);
+        $build['node_table'][$delta]['type']['#markup'] = SafeMarkup::checkPlain($node['type']);
+        $build['node_table'][$delta]['created']['#markup'] = SafeMarkup::checkPlain($node['created']);
+        $build['node_table'][$delta]['edit']['#markup'] = $this->l($this->t('Edit'), new Url('rest_example.client_actions_edit', array('id' => SafeMarkup::checkPlain($node['nid']))));
+        $build['node_table'][$delta]['delete']['#markup'] = $this->l($this->t('Delete'), new Url('rest_example.client_actions_delete', array('id' => SafeMarkup::checkPlain($node['nid']))));
+      }
+    }
+
+    return $build;
+  }
+
+}
diff --git a/rest_example/src/Form/RestExampleClientDelete.php b/rest_example/src/Form/RestExampleClientDelete.php
new file mode 100644
index 0000000..2b4ae8a
--- /dev/null
+++ b/rest_example/src/Form/RestExampleClientDelete.php
@@ -0,0 +1,85 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\rest_example\Form\RestExampleClientSettings.
+ */
+
+namespace Drupal\rest_example\Form;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Form\ConfirmFormBase;
+use Drupal\Core\Url;
+use Drupal\rest_example\RestExampleClientCalls;
+
+/**
+ * Delete a new node on a remote Drupal site.
+ *
+ * @ingroup rest_example
+ */
+class RestExampleClientDelete extends ConfirmFormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'rest_example_client_delete';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getQuestion() {
+    return $this->t('Are you sure that you want to delete this content.');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCancelUrl() {
+    return new Url('rest_example.client_actions_index');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfirmText() {
+    return t('Delete');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, FormStateInterface $form_state) {
+    if (is_null($form_state->get('node_id')) || !is_numeric($form_state->get('node_id'))) {
+      $form_state->setErrorByName('delete', $this->t('The ID passed in the URL is not an integer'));
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state, $id = NULL) {
+    $form = parent::buildForm($form, $form_state);
+
+    $form_state->set('node_id', $id);
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $node_id = $form_state->get('node_id');
+
+    $node = array(
+      'nid' => $node_id,
+    );
+
+    $client = new RestExampleClientCalls(\Drupal::httpClient());
+    $client->delete($node);
+    $form_state->setRedirect('rest_example.client_actions_index');
+  }
+
+}
diff --git a/rest_example/src/Form/RestExampleClientEdit.php b/rest_example/src/Form/RestExampleClientEdit.php
new file mode 100644
index 0000000..60469b7
--- /dev/null
+++ b/rest_example/src/Form/RestExampleClientEdit.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\rest_example\Form\RestExampleClientSettings.
+ */
+
+namespace Drupal\rest_example\Form;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Form\FormBase;
+use Drupal\rest_example\RestExampleClientCalls;
+use Symfony\Component\HttpFoundation\Response;
+
+/**
+ * Edit or create a new node on a remote Drupal site.
+ *
+ * @ingroup rest_example
+ */
+class RestExampleClientEdit extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'rest_example_client_edit';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, FormStateInterface $form_state) {
+    if (!is_null($form_state->get('node_id')) && !is_numeric($form_state->get('node_id'))) {
+      $form_state->setErrorByName('submit', $this->t('The ID passed in the URL is not an integer'));
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state, $id = NULL) {
+    if (!is_null($id) && !is_numeric($id)) {
+      return new Response('The ID passed in the URL is not an integer', 500);
+    }
+
+    $title = '';
+    $form_state->set('node_id', NULL);
+    $form_state->set('node_type', 'rest_example_test');
+
+    // If this an existing node, we pull the data from the remote and set the
+    // variables that we use as default values later on.
+    if (is_numeric($id)) {
+      $client = new RestExampleClientCalls(\Drupal::httpClient());
+      $node = $client->index($id);
+      if (isset($node[0])) {
+        $title = $node[0]['title'];
+        $form_state->set('node_id', $id);
+      }
+    }
+
+    $form['title'] = array(
+      '#type' => 'textfield',
+      '#title' => $this->t('Node title'),
+      '#default_value' => $title,
+    );
+
+    $form['submit'] = array(
+      '#type' => 'submit',
+      '#value' => $this->t('Save'),
+    );
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $node_id = $form_state->get('node_id');
+    $node_type = $form_state->get('node_type');
+    $form_values = $form_state->getValues();
+
+    $node = array(
+      'nid' => $node_id,
+      'title' => $form_values['title'],
+      'type' => $node_type,
+    );
+
+    $client = new RestExampleClientCalls(\Drupal::httpClient());
+    if (is_null($node_id)) {
+      $client->create($node);
+    }
+    else {
+      $client->update($node);
+    }
+
+    $form_state->setRedirect('rest_example.client_actions_index');
+  }
+
+}
diff --git a/rest_example/src/Form/RestExampleClientSettings.php b/rest_example/src/Form/RestExampleClientSettings.php
new file mode 100644
index 0000000..45c113d
--- /dev/null
+++ b/rest_example/src/Form/RestExampleClientSettings.php
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\rest_example\Form\RestExampleClientSettings.
+ */
+
+namespace Drupal\rest_example\Form;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Form\ConfigFormBase;
+
+/**
+ * Setup form for a Drupal REST client.
+ *
+ * Here you configure what the other Drupal installation.
+ *
+ * @ingroup rest_example
+ */
+class RestExampleClientSettings extends ConfigFormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'rest_example_client_settings';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $form['intro'] = array(
+      '#markup' => t('Set here the remote server options.'),
+    );
+    $form['server_url'] = array(
+      '#type' => 'textfield',
+      '#title' => $this->t('Remote server URL'),
+      '#description' => $this->t('Format like this: http://www.example.com or http://www.example.com/test-site (no trailing slash)'),
+      '#default_value' => $this->config('rest_example.settings')->get('server_url'),
+      '#required' => TRUE,
+    );
+    $form['server_username'] = array(
+      '#type' => 'textfield',
+      '#title' => $this->t('Remote server username'),
+      '#default_value' => $this->config('rest_example.settings')->get('server_username'),
+      '#description' => $this->t('A user on the remote system that has the proper rights to use the REST service'),
+      '#required' => TRUE,
+    );
+    $form['server_password'] = array(
+      '#type' => 'textfield',
+      '#title' => $this->t('Remote server password'),
+      '#default_value' => $this->config('rest_example.settings')->get('server_password'),
+      '#description' => $this->t('Remote users password'),
+      '#required' => TRUE,
+    );
+    return parent::buildForm($form, $form_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $form_values = $form_state->getValues();
+
+    $this->config('rest_example.settings')
+        ->set('server_url', $form_values['server_url'])
+        ->set('server_username', $form_values['server_username'])
+        ->set('server_password', $form_values['server_password'])
+        ->save();
+
+    parent::submitForm($form, $form_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getEditableConfigNames() {
+    return array(
+      'rest_example.settings',
+    );
+  }
+}
diff --git a/rest_example/src/RestExampleClientCalls.php b/rest_example/src/RestExampleClientCalls.php
new file mode 100644
index 0000000..8303fdf
--- /dev/null
+++ b/rest_example/src/RestExampleClientCalls.php
@@ -0,0 +1,229 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\rest_example\RestExampleClientCalls.
+ */
+
+namespace Drupal\rest_example;
+
+use Drupal\Component\Serialization\Json;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use GuzzleHttp\ClientInterface;
+use Symfony\Component\HttpFoundation\Response;
+
+/**
+ * Here we interact with the remote service.
+ *
+ * We use Guzzle (what else ;-) ).
+ */
+class RestExampleClientCalls {
+
+  /**
+   * The client used to send HTTP requests.
+   *
+   * @var \GuzzleHttp\ClientInterface
+   */
+  protected $client;
+
+  /*
+   * The header uses when sending HTTP request.
+   *
+   * The headers are very important when communicating with the REST server.
+   * It's used by the server the verify that it supports the sent data
+   * (Content-Type) and that it supports the type of response that the client
+   * wants.
+   *
+   * @var array
+   */
+  protected $clientHeaders = array(
+    'Accept' => 'application/hal+json',
+    'Content-Type' => 'application/hal+json',
+  );
+
+  /* The authentication parameters, used when calling the remote
+   * REST server.
+   *
+   * @var array
+   */
+  protected $clientAuth;
+
+  /* The URL of the remote REST server.
+   *
+   * @var string
+   */
+  protected $remoteUrl;
+
+  /**
+   * The constructor.
+   *
+   * @param GuzzleHttp\ClientInterface $client
+   *   The HTTP client.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The Config Factory.
+   */
+  public function __construct(ClientInterface $client, ConfigFactoryInterface $config_factory) {
+    $this->client = $client;
+
+    // Retrieve the config from the configuration page set at
+    // examples/rest_client_settings.
+    $rest_config = $config_factory->get('rest_example.settings');
+
+    $this->clientAuth = array(
+      $rest_config->get('server_password'),
+      $rest_config->get('server_username'),
+    );
+
+    $this->remoteUrl = $rest_config->get('server_url');
+  }
+
+  /**
+   * Retrieve a list of nodes from the remote server.
+   *
+   * When we retrive entities we use GET.
+   *
+   * @param int $node_id
+   *   The ID of the remote node, if needed. If the ID is NULL, all nodes will
+   *   be fetched.
+   *
+   * @return string
+   *   JSON formatted string with the nodes from the remote server.
+   */
+  public function index($node_id = NULL) {
+
+    // If the configurated URL is an empty string, return nothing.
+    if (empty($this->remoteUrl)) {
+      return '';
+    }
+
+    $id = '';
+    if (!empty($node_id) && is_numeric($node_id)) {
+      $id = '/' . $node_id;
+    }
+
+    $response = $this->client->get(
+      $this->remoteUrl . '/rest/node' . $id, array(
+        'headers' => $this->clientHeaders,
+        // TODO: Uncomment this when Guzzle authetication and
+        // Basic Authentication works with Views. For now, Drupal just chockes
+        // in the request, if auth is sent in the request.
+        //'auth' => $this->clientAuth,
+      )
+    );
+
+    return Json::decode($response->getBody()->getContents());
+  }
+
+  /**
+   * Create a node on the remote server, using POST.
+   *
+   * @param array $node
+   *   Contains the data of the node we want to create.
+   *
+   * @return Symfony\Component\HttpFoundation\Response
+   *   A HTTP response.
+   */
+  public function create(array $node) {
+
+    if (empty($this->remoteUrl)) {
+      return new Response('The remote URL has not been setup.', 500);
+    }
+
+    // Build an array of options telling the remote server what type of content
+    // we want to create, and give it a title. After that, we encode it all
+    // to JSON.
+    $request_body = json_encode(array(
+      '_links' => array(
+        'type' => array(
+          'href' => $this->remoteUrl . '/rest/type/node/' . $node['type'],
+        ),
+      ),
+      'title' => array(0 => array('value' => $node['title'])),
+    ));
+
+    $response = $this->client->post(
+        $this->remoteUrl . '/entity/node',
+        array(
+          'headers' => $this->clientHeaders,
+          'auth' => $this->clientAuth,
+          'body' => $request_body,
+        )
+      );
+
+    // Validate the response from the remote server.
+    if ($response->getStatusCode() != 201) {
+      return new Response('An error occured while creating the node.', 500);
+    }
+  }
+
+  /**
+   * Update (PATCH) a node on the remote server.
+   *
+   * You are encuraged to read the code and the comments in
+   * RestExampleClientCalls::create() first.
+   *
+   * @param array $node
+   *   Contains the data of the node we want to create.
+   *
+   * @return Symfony\Component\HttpFoundation\Response
+   *   A HTTP response.
+   */
+  public function update(array $node) {
+    if (empty($this->remoteUrl)) {
+      return new Response('The remote URL has not been setup.', 500);
+    }
+
+    $request_body = json_encode(array(
+      '_links' => array(
+        'type' => array(
+          'href' => $this->remoteUrl . '/rest/type/node/' . $node['type'],
+        ),
+      ),
+      'title' => array(0 => array('value' => $node['title'])),
+    ));
+    $response = $this->client->patch(
+        $this->remoteUrl . '/node/' . $node['nid'],
+        array(
+          'headers' => $this->clientHeaders,
+          'auth' => $this->clientAuth,
+          'body' => $request_body,
+        )
+      );
+
+    if ($response->getStatusCode() != 204) {
+      return new Response('An error occured while patching the node.', 500);
+    }
+  }
+
+  /**
+   * Delete a node on the remote server, using DELETE.
+   *
+   * You are encuraged to read the code and the comments in
+   * RestExampleClientCalls::create() first.
+   *
+   * @param array $node
+   *   Contains the data of the node we want to create.
+   *
+   * @return Symfony\Component\HttpFoundation/Response
+   *   An HTTP response.
+   */
+  public function delete(array $node) {
+
+    if (empty($this->remoteUrl)) {
+      return new Response('The remote URL has not been setup.', 500);
+    }
+
+    $response = $this->client->delete(
+        $this->remoteUrl . '/node/' . $node['nid'],
+        array(
+          'headers' => $this->clientHeaders,
+          'auth' => $this->clientAuth,
+        )
+      );
+
+    if ($response->getStatusCode() != 204) {
+      return new Response('An error occured while patching the node.', 500);
+    }
+  }
+
+}
diff --git a/rest_example/src/Tests/RestExampleMenuTest.php b/rest_example/src/Tests/RestExampleMenuTest.php
new file mode 100644
index 0000000..8372ab0
--- /dev/null
+++ b/rest_example/src/Tests/RestExampleMenuTest.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\rest_example\Tests\RestExampleMenuTest.
+ */
+
+namespace Drupal\rest_example\Tests;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Test the user-facing menus in Rest Example.
+ *
+ * @ingroup rest_example
+ * @group rest_example
+ * @group examples
+ */
+class RestExampleMenuTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('rest_example');
+
+  /**
+   * The installation profile to use with this test.
+   *
+   * This test class requires the "Tools" block.
+   *
+   * @var string
+   */
+  protected $profile = 'minimal';
+
+  /**
+   * Test for a link to the rest example in the Tools menu.
+   */
+  public function testRestExampleLink() {
+    $this->drupalGet('');
+    $this->assertLinkByHref('examples/rest_client_actions');
+    $this->assertLinkByHref('examples/rest_client_settings');
+  }
+
+  /**
+   * Tests rest_example menus.
+   */
+  public function testRestExampleMenu() {
+    $this->drupalGet('examples/rest_client_actions');
+    $this->assertResponse(200, 'Action page exists.');
+
+    $this->drupalGet('examples/rest_client_settings');
+    $this->assertResponse(200, 'Settings page exists.');
+  }
+
+}
