Drupal
min read
July 12, 2023
August 1, 2022

CRUD Operations in Decoupled Drupal: A 101 Guide

CRUD Operations in Decoupled Drupal: A 101 Guide
Table of contents

CRUD in computer programming refers to the functions required to perform different operations on specific data within a database. CRUD stands for Create, Read, Update, and Delete. CRUD operations are widely used in applications supported by relational databases.

In this blog, we will look at how to perform CRUD operations utilizing a simple JavaScript front-end system and the Drupal core’s JSON API module.

What is Decoupled Drupal?

Decoupled Drupal refers to a Drupal architecture where Drupal’s back-end exposes content to other front-end systems, essentially serving as a central repository of content that can be served to a wide variety of devices.

What are the advantages of Decoupled Drupal?

A decoupled Drupal architecture enables the development team to take advantage of Drupal’s highly regarded back-end functionality, using Drupal as a repository for content that can be made available to other front-end systems.

Drupal’s JSON API

Drupal Core provides a module named JSON API which provides us with a REST API. This provided API is centered on Drupal’s entity types and bundles. It simply means that the JSON API module converts all the entity types, bundles, etc into a REST API representation. For example, articles, pages, and users are given the types: node--article, node--pages, and user--user, respectively.

To learn more about the JSON API module, click here.

Objective

To understand how CRUD operations are done using the JSON API module used in a Decoupled Drupal Application.

Pre-requisites

Make sure you have a freshly installed Drupal site up and running. That's it!

Authentication using JSON API

  • CRUD operations can only be performed by the authenticated user.
  • To authenticate a user using JSON API, we need to make a POST request to the Drupal Back-end.
  • The body parameter of the POST request must contain the username and password in a JSON format.
  1. Create a JSON body for the request, this JSON body will contain the username and password of the user.

const userData = {
   name: <user-name>,
   pass: <user-password>,
 };
  1. Making the final request.

const response = await fetch("http://example.org/web/user/login?_format=json"
, {
   method: "POST",
   headers: {
     "Content-Type": "application/json",
   },
   body: JSON.stringify(userData), // JSON body goes here
 });
  • This HTTP request will provide us with two tokens.
  1. CSRF token.
  2. Logout token
  • The CSRF token can prevent CSRF attacks by making it impossible for an attacker to construct a fully valid HTTP request suitable for feeding to a victim user.
  • The Logout token can be used as a parameter when logging out of the website.
  • It is recommended to store these tokens in some sort of memory, for example, browser cookies, so that they can be accessed whenever required.
  • For example, to make CRUD operations, the CSRF token is required whereas while logging out, the Logout token is required.

Enabling the JSON API module

  • The JSON API module is a core module available to us OOTB (Out-of-the-box) when we install Drupal.
  • To enable the JSON API module in Drupal CMS, follow the below-mentioned steps :
  • Log in as administrator.
  • Go to the extend tab, present in the admin toolbar (admin/modules)
  • Make sure you are on the List tab of the extend page.
  • In the search bar, search for the JSON API module.
  • Select the JSON API module by clicking the checkbox.
  • Click on Install.
  • The installation process requires the Serialization module to be installed.
  • It will enable the JSON API module.
  • After installing the JSON API module, let's see how to use it.

Using the JSON API module

  • A JSON: API URL looks like this:

GET|POST           /jsonapi/node/article 
PATCH|DELETE       /jsonapi/node/article/{uuid}
  • Every resource type must be uniquely addressable in the API.
  • The Drupal implementation follows the pattern:

/jsonapi/{entity_type_id}/{bundle_id}[/{entity_id}]
  • The URL is always  prefixed by /jsonapi.
  • A simple jsonapi request can be made like

http://localhost/drupal_movie/web/jsonapi/<entity-type>/<bundle>
  • Enter the following URL in the URL tab :

http://localhost/<your-drupal-instance-name>/web/jsonapi
  • Example :

http://localhost/drupal_movie/web/jsonapi
OR
http://example.org/web/jsonapi
  • Make sure the URL ends with the term jsonapi.
  • This URL will generate the following kind of output :

{ "jsonapi": 
  { "version": "1.0",     "meta": { 
       "links": 
          { "self": { "href": "http://jsonapi.org/format/1.0/" } } } }, "data": [],
 "meta": { "links": { "me": { "meta": { "id": "5aa9df1f-5562-4c0e-84f8-055561d6b4cf"
 }, "href": ​
"http://localhost/drupal_movie/web/jsonapi/user/user/5aa9df1f-5562-4c0e-84f8-055561
d6b4cf"  } } }, "links": { "action--action": { "href": 
"http://localhost/drupal_movie/web/jsonapi/action/action" }, 
"base_field_override--base_field_override": { "href": "http://localhost/drupal_movie/web/jsonapi/base_field_override/base_field_override" 
 }, "block--block": { "href": 
"http://localhost/drupal_movie/web/jsonapi/block/block" }, . . . . "user--user": { 
"href": "http://localhost/drupal_movie/web/jsonapi/user/user" }, 
"user_role--user_role": { "href": 
"http://localhost/drupal_movie/web/jsonapi/user_role/user_role" }, "view--view": {  
"href": 
  • As you can see, the JSON API module converts all the Drupal data into JSON representation.
  • This makes the JSON API module one of the most useful core modules in Drupal.
  • Now you can fetch the required data, add new data or alter the existing data by making a HTTP request.
  • Example:
  • We want a list of all articles in JSON, do the following :
  • In URL tab enter :

http://localhost/drupal_movie/web/jsonapi/node/article
OR
http://example.org/web/jsonapi/node/article
  • It will give a list of all the nodes of the article content type or bundle in the Drupal site.
  • The output will look something like this :


{ 
"jsonapi": { 
"version": "1.0", 
"meta": { 
"links": { 
"self": { 
"href": "http://jsonapi.org/format/1.0/" 
} 
} 
} 
}, 
"data": [ 
{ 
"type": "node--article", 
"id": "a90b4731-c573-4503-b893-9825a416ed68", 
"links": { 
"self": { 
"href": "http://localhost/drupal_movie/web/jsonapi/node/article/a90b4731-c573-4503-b893-982 
5a416ed68?resourceVersion=id%3A52" 
} 
}, 
"attributes": { 
"drupal_internal__nid": 47, 
"drupal_internal__vid": 52, 
"langcode": "en", 
"revision_timestamp": "2022-04-22T10:22:58+00:00", 
"revision_log": null, 
"status": true, 
"title": "The Process of UX Design at QED42", 
"created": "2022-04-22T10:22:07+00:00", 
"changed": "2022-04-22T10:22:58+00:00", 
"promote": true, 
"sticky": false, 
"default_langcode": true,  
"revision_translation_affected": true, 
"content_translation_source": "und", 
"content_translation_outdated": false, 
"body": { 
"value": "<p>The idea behind having a process isn't just about trying to be 
organized amidst the chaos. While it does play an important part in giving us 
trusted and well-structured ways of performing tasks, it doesn't always stand true 
on every project. In reality, as every project has certain requirements, trying to 
work it out using a particular process, doesn't hold 
much sense.</p>\r\n\r\n<p>Having said this, we do have a specific process in place 
that we like to follow, along with certain additions and subtractions, as per 
project needs. While sometimes the process stays as linear as can be, sometimes it's a 
combination of pieces, while other times we decide to follow something completely 
new, while trying to stick to the basics.</p>\r\n\r\n<p>Nonetheless, QED42 does 
have six core steps that we mostly stick to while phasing out, as per project 
needs. Our process and how we go about it completely depend on the project at hand, 
business vision and values, and most importantly on people who are going to be 
using that product.</p>\r\n", 
"format": "basic_html", 
"processed": "<p>The idea behind having a process isn't just about trying to be 
organized amidst the chaos. While it does play an important part in giving us 
trusted and well-structured ways of performing tasks, it doesn't always stand true 
on every project. In reality, as every project has certain requirements, trying to 
work it out using a particular process, doesn't hold much sense.</p>\n\n<p>Having 
said this, we do have a specific process in place that we like to follow, along 
with certain additions and subtractions, as per project needs. While sometimes the 
process stays as linear as can be, sometimes it's a combination of pieces, while 
other times we decide to follow something completely new, while trying to stick to 
the basics.</p>\n\n<p>Nonetheless, QED42 does have six core steps that we mostly 
stick to while phasing out, as per project needs. Our process and how we go about 
it completely depend on the project at hand, business vision and values, and most 
importantly on people who are going to be using that product.</p>", 
.
.
.
  • In a similar way, you can access any entity bundle like a basic page (jsonapi/node/page).
  • To access taxonomy terms, the following HTTP request can be made.

http://localhost/drupal_movie/web/jsonapi/taxonomy_term/tags
OR
http://example.org/web/jsonapi/taxonomy_terms/tags

Format : 
http://domain/web/jsonapi/taxonomy_tags/<vocabulary-machine-name>
  • and you will get the entire list of the taxonomies present in tags vocabulary.
  • If you want to target a specific article, we need to append the UUID of the particular article to the HTTP request.
  • Example:

http://localhost/drupal_movie/web/jsonapi/node/article/a90b4731-c573-
4503-b893-9825a416ed68

Format : 
http://domain/web/jsonapi/node/article/<UUID-of-the-specific-article>
  • To learn more about the JSON API module, click here

Creating a Client Secret

Before we move forward, we need a client_id and client_secret, as these terms will be necessary to generate an authorized access token. There is a contributed module in Drupal for generating a client_id and client_secret, the simple OAuth module.

Using the Simple OAuth module :

  • Using this module, we will generate a client_id and a client_secret.

Download the module

  • Using composer:
  • In terminal : composer require drupal/simple_oauth

Enable the module

  • Using drush: drush en simple_oauth
  • Using admin UI :
  • Login as administrator.
  • Go to the extend tab, present in the admin toolbar admin/modules
  • Make sure you are on the List tab of the extend page.
  • In the search bar, search for the Simple OAuth module.
  • Select the Simple OAuth module by clicking the checkbox.
  • Click on Install.
  • The module will be enabled.

Create the client secret

To create a client secret, follow the below-mentioned steps :

  1. Go to the configuration page - admin/config
  2. Under people, select Simple Oauth - admin/config/people/simple_oauth
  3. Select Add client action link
  4. Fill in the details
  5. Note down the New secret field’s data as we will need it in the further process. This data is basically your client-secret data
  6. Click save.
  • The client secret has been created
  • Note the UUID of the client, which is known as ‘client_id’, and the scope of the client for the scope header of the HTTP request
  • So now we have the client_id and client_secret and the client-scope

CRUD operations in Decoupled Drupal

  • There are 4 main operations that most of the users do on a regular basis.
  • Create, Read, Update and Delete.

Create Operation

  • To create some content in a Decoupled Drupal site, we have to make a POST request to the Drupal Back-end.
  • To make a Post request, you need an authorized JSON Web Token (JWT) and a CSRF token.
  • JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties.
  • A CSRF token is a secure random token (e.g., synchronizer token or challenge token) that is used to prevent CSRF attacks.
  • The token needs to be unique per user session and should be of large random value to make it difficult to guess.
  • The CSRF token is provided when the user is authenticated.
  • A CSRF secure application assigns a unique CSRF token for every user session.
  • That means every time the user logs in a new token is generated which prevents the attack on the site.
  • Steps to make a POST request using JSON API in Drupal.

First, generate the access token (JWT) for a user.

  • URL

http://localhost/drupal_movie/web/oauth/token
  • Request Body/Params -
  • grant_type : password
  • client_id : <client-id>
  • client_secret : <client-secret>
  • username : Admin (Drupal User)
  • password : 123 (Drupal password)
  • scope : <client-scope>

Making the request to Drupal.

  • URL

http://localhost/drupal_movie/web/jsonapi/node/article

Headers -

  • Authorization: Bearer <access-token-goes-here>
  • Headers:
  • Content-Type : application/vnd.api+json
  • Accept : application/vnd.api+json
  • “X-CSRF-Token”: <csrf-token-goes-here>
  • Body: select ‘raw’

 {
  "data": {
    "type": "node--article",
    "attributes": {
      "title": "How DXPs help e-commerce brands create memorable 
experiences",
      "body": {
        "value": "Marquee brands like Forever 21 and Yelp offer 
personalized experiences on their homepage. They provide customized 
recommendations for user preferences, such as likes and dislikes, 
food preferences, and lifestyles, to meet customer needs better. The 
new features on the Yelp app have earned them 2.4 million users a 
month, with 2.2 million requests from across 300+ categories. The 
Californian fashion giant Forever 21 has been prioritizing 
personalization. They capture customer attention with personalized 
search results, lucrative offers, and product recommendations. This 
article discusses digital experience platforms and how they play an 
important role in creating a great digital customer experience for 
customer loyalty, retention, and lifetime value. It also covers how 
digital experience platforms can elevate customers' brand experience 
and ultimately business for brands.",
        "format": "basic_html",
        "summary": "Marquee brands like Forever 21 and Yelp offer 
personalized experiences on their homepage. They provide customized 
recommendations for user preferences, such as likes and dislikes, 
food preferences, and lifestyles, to meet customer needs better. The 
new features on the Yelp app have earned them 2.4 million users a 
month, with 2.2 million requests from across 300+ categories."
      }
    }
  }
}
  • The article data should be represented in JSON format.
  • It will generate either a bad request or the article will be created and we will receive this newly created article in JSON response.
  • If a bad request is generated, it means something is wrong with our custom request.

Read Operation

  • To read or search any content, we can make a GET request.
  • Here, the filtering feature of the JSON API is very useful.
  • For example: We want to search for an article using the title, so our HTTP request will be something like this :

http://localhost/drupal_movie/web/jsonapi/node/article?filter[title][
value]=<article-title>
  • Here using filters, we can fetch the entire requested article in a single request, which enhances the time complexity of the request-response cycle.

Update Operation

  • To update any content, we can fire a POST request which contains the updated content and a CSRF token.
  • The request will look something like this

let url = "http://localhost/drupal_movie/web/jsonapi/node/article/" + 
uuid; 

const reqBody = { 
  data: { 
    type: "node--article", 
    id: uuid, 
    attributes: { 
       title: title, 
       body: { 
          value: body, 
          format: "basic_html", 
          summary: summary, 
        }, 
      },
    },
  }; 

let response = await axios({  
    method: "PATCH", 
    url: url, 
    headers: { 
         "Content-Type": "application/vnd.api+json", 
         "X-CSRF-Token": csrf_token, 
    }, data: reqBody, 
});
  • Here UUID is the unique id of the particular content we want to update.

Delete Operation

  • To delete a particular content, we can make a DELETE request to the Drupal BE.
  • We need the UUID of the article we want to delete
  • This delete request must contain a few important headers :
  • ‘Content-Type’
  • ‘X-CSRF-Token’
  • The final DELETE request will look something like this :

let response = await axios({
       method: 'DELETE',
       url: 
`http://localhost/drupal_movie/web/jsonapi/node/article/${uuid}`,
       headers: {
           'Content-Type': 'application/vnd.api+json',
           "X-CSRF-Token": csrf_token,
       }
   });
  • The requested article will be deleted.

CRUD operations are crucial and frequently used in database and database design cases. The above example explains how we can perform CRUD operations on a Drupal Back-end using the JSON API. While there are many other examples to achieve the same, the premise and ideology remain constant.

Written by
Editor
No art workers.