Skip to header Skip to main navigation Skip to main content Skip to footer
  • Log in
Home
DrupalVIP
Freelancer service with great care and enthusiasm.
  • Home
  • Products
  • Blog
  • Support
    • Dictionary
    • Drupal Resources
    • External Resources

Requests and Responses the Drupal way

Breadcrumb

  • Home
  • DrupalVIP Support
  • Requests and Responses the Drupal way

Building your own REST API:

Symfony's Response objects are fully supported, but are insufficient to fully support the rich Drupal ecosystem: we need more structured metadata than the very simple Symfony Response objects can provide.
Unfortunately, Symfony Response objects do not have an interface: every specialized Response "type" needs to extend from Symfony's Response base class.

Drupal core defines two response interfaces that any response can implement to indicate it supports these particular Drupal capabilities.

CacheableResponseInterface  An interface for responses that can expose cacheability metadata. 
(Cache contexts, tags and max-age.)
Note: can easily be implemented by using the corresponding CacheableResponseTrait.
See CacheableResponseInterface for more about this!

AttachmentsInterface  An interface for responses that can expose #attached metadata. 
(Asset libraries, <head> elements, placeholders …)
Note: can easily be implemented by using the corresponding AttachmentsTrait.

CacheableResponse  A response that contains and can expose cacheability metadata. 
Supports Drupal's caching concepts: cache tags for invalidation and cache contexts for variations.
This is simply class CacheableResponse extends Response implements CacheableResponseInterface {}.

HtmlResponse  This is what a controller returning a render array will result in after going through the Render API and its render pipeline.
This is simply class HtmlResponse extends Response implements CacheableResponseInterface, AttachmentsInterface {}.

CacheableJsonResponse  A JsonResponse that contains and can expose cacheability metadata.
This is simply class CacheableJsonResponse extends JsonResponse implements CacheableResponseInterface {} — i.e. it extends Symfony's JsonResponse.

CacheableRedirectResponse  A RedirectResponse that contains and can expose cacheability metadata.
This is simply class CacheableRedirectResponse extends RedirectResponse implements CacheableResponseInterface {} — i.e. it extends Symfony's RedirectResponse.

LocalRedirectResponse  A redirect response which cannot redirect to an external URL. 
(Extends CacheableRedirectResponse.)

TrustedRedirectResponse  A redirect response which should only redirect to a trusted (potentially external) URL. 
(Also extends CacheableRedirectResponse.)

 

Core Module: RESTful Web Services

This module when activated support the following API:

  1. Users API
    1. Login
      1. POST http://example.com/user/login?_format=json
      2. Content-type: application/json
      3. withCredentials: true (only for cross domain authentication)
        {
          "name": "admin",
          "pass": "password"
        }
      4. return: 200 OK
    2. Logout
      1. POST http://example.com/user/logout?_format=json&token=logout_token
      2. Content-type: application/json
      3. withCredentials: true (only for cross domain authentication)
      4. return: 204 - OK
    3. Retrieve
      1. GET http://example.com/user/1?_format=json
      2. None
      3. return: 200 - OK
    4. Register
      1. POST: https://example.com/user/register?_format=json
      2. Content-type: application/json
        {
         "name": { "value": "fooBar" },
         "mail": { "value": "foo@bar.com" },
         "pass": { "value": "secretSauce" }
        }
      3. return: 200 OK
  2. Node API
    1. Create
      1. POST: http://example.com/entity/node
      2. Content-type: application/json
        {
         "type":[{"target_id":"article"}],
         "title":[{"value":"Hello World"}],
         "body":[{"value":"How are you?"}]
        }
      3. return: 201 - Created
      4. For setting the value of an entity reference field referencing another entity type, all you need is its uuid:
        "_embedded": {
         "https://example.com/rest/relation/node/article/my_entity_reference_field": [
           { 
             "uuid":[{"value":"yourUUID-xxx-xxxx-xxxx-xxxxxxxxx"}]
           }
         ]
        }
    2. Retrieve
      1. GET: http://example.com/node/123?_format=json
      2. Content-type: *
      3. Accept: application/json
      4. return: 200 - OK
    3. Update
      1. PATCH: http://example.com/node/123
      2. Content-type: application/json
        {
         "nid":[{"value":"123"}],
         "type":[{"target_id":"article"}],
         "title":[{"value":"Goodbye World"}]
        }
      3. return: 204 - No Content
    4. Delete
      1. DELETE: http://example.com/node/123
      2. Content-type: *
        {"type":[{"target_id":"article"}]}
      3. return: 204 - No Content

         

Results are Automatically Cached from GET Requests
While developing, it's important to understand that when you make a GET request to D8 Rest, Drupal will cache the result so subsequent requests receive a speedy response. You can either clear all of Drupal's caches to get the new results, or append a timestamp to the URL query string:

node/123?_format=json&time=123456789

Or if you've created a custom resource, use addCacheableDependency() on the ResourceResponse:

$response = new ResourceResponse(array('hello' => 'world'));
$response->addCacheableDependency($account);
return $response;

Drupal Development

Drupal Development
Code Snippet

RESTful Example using jQuery and core REST module

CREATE Item

var package = {}
package.title = [{'value':'t1'}]
package.body = [{'value':'b1'}]
package._links = {"type":{"href":"http://local.drupal8.org/rest/type/node/page"}}
$.ajax({
  url: "http://example.com/entity/node",
  method: "POST",
  data: JSON.stringify(package),
  headers: {
    "Accept": "application/json",
    "Content-Type": "application/hal+json"
  },
  success: function(data, status, xhr) {
    debugger
  }
})

GET Item

$.ajax({
  url: "http://example.com/node/3?_format=hal_json",
  method: "GET",
  headers: {
    "Content-Type": "application/hal+json"
  },
  success: function(data, status, xhr) {
    debugger
  }
})

GET an Item and then UPDATE Item

$.ajax({
  url: "http://example.com/node/3?_format=hal_json",
  method: "GET",
  headers: {
    "Content-Type": "application/hal+json"
  },
  success: function(data, status, xhr) {
    var package = {}
    package.title = data.title
    package.body = data.body
    package.title[0].value = 'yar'
    package._links = {"type":{"href":"http://example.com/rest/type/node/page"}}
    debugger

    $.ajax({
      url: "http://example.com/node/3",
      method: "PATCH",
      data: JSON.stringify(package),
      headers: {
        "X-CSRF-Token": "niCxgd5ZZG25YepbYtckCy7Q2_GL2SvMUY5PINxRAHw",
        "Accept": "application/json",
        "Content-Type": "application/hal+json"
      },
      success: function(data, status, xhr) {
        debugger
      }
    })
  }
})

Drupal protects its REST resources from CSRF attacks by requiring a X-CSRF-Token request header to be sent when using a non-safe method. So, when performing non-read-only requests, that token is required. 
Such a token can be retrieved at /session/token.

GET an Item and then UPDATE Item with CSRF token.

$.ajax({
  url: 'http://example.com/session/token',
  method: 'GET',
  success: function(token) {
    var csrfToken = token;

    $.ajax({
      url: "http://example.com/node/3?_format=hal_json",
      method: "GET",
      headers: {
        "Content-Type": "application/hal+json"
      },
      success: function(data, status, xhr) {
        var package = {};
        package.title = data.title;
        package.body = data.body;
        package.title[0].value = 'yar';
        package._links = {"type":{"href":"http://example.com/rest/type/node/page"}};
        debugger

        $.ajax({
          url: "http://example.com/node/3",
          method: "PATCH",
          data: JSON.stringify(package),
          headers: {
            "X-CSRF-Token": csrfToken,
            "Accept": "application/json",
            "Content-Type": "application/hal+json"
          },
          success: function(data, status, xhr) {
            debugger;
          }
        });
      }
    });
  }
});

DELETE Item

$.ajax({
  url: "http://example.com/node/3",
  method: "DELETE",
  headers: {
    "Accept": "application/json",
    "Content-Type": "application/hal+json"
  },
  success: function(data, status, xhr) {
    debugger
  }
})
Read More
Monolithic and Decoupled Drupal Architectures
Responses overview
JavaScript and Drupal 8 RESTful Web Services
How To Request A Node via REST Using Web Services in Drupal 8
jDrupal
Tags
Drupal Support
Drupal 10
response
Drupal Response
HtmlResponse
JsonResponse
RESTful Web Services
Ajax
Code Snippet
Ajax Example
ResourceResponse

The Freelancer Assistance

Drupal Training

drupal training session

Site Management

Site Management

Proactive Maintenance

Proactive Maintenance

Drupal Development

Drupal Development

Drupal Shared Space

Drupal Shared Space

Fullstack Service

Fullstack Service
Review All Services

Buy Hourly Support

 

Drupal platform support for complex websites. The service includes support, training, troubleshooting, fixes, updates, tool creation and module building.
* Minimum order is for 5 hours of support
* For every 20 hours of order you will be entitled to an additional hour of support
* For every 50 hours of order you will be entitled to 5 additional hours of support

 

>> Payment <<

 
cards

מופעל על-ידי paypal

Legal

  • Home
  • Contact
  • Products

Footer menu

  • Home
  • Contact
  • Products

Copyright © 2026 DrupalVIP project of Automatic Frameworks - All rights reserved

Developed and Maintain by Jonathan Ben Hur Freelancer