How to use Webform Rest module with Drupal 9: A Practical Use Guide
Tags: drupal, webform, rest
Published: 2023-06-27 18:54:22

In the ever-evolving world of web development, **Drupal 9** remains one of the most reliable and flexible platforms for building websites and applications. With its modular architecture, Drupal allows developers to extend and customize its functionalities to meet the specific needs of a project.

In this article, we will explore the **[Webform Rest module](https://www.drupal.org/project/webform_rest)**, a valuable extension for Drupal 9 that enables external applications to communicate with Drupal through **RESTful APIs**. This introductory tutorial details how to leverage the module, providing an overview of its functionalities and demonstrating how to use it in a Drupal 9 application.

The topics covered in this article include:

1. Module overview
2. Requirements
3. How to install the Webform Rest and Rest UI modules
4. How to configure the Webform Rest module
5. A word about CORS
6. How to make requests with Webform Rest
7. Request and response payloads.

## Module Overview: Webform Rest

The Webform Rest module is a powerful extension that integrates the functionality of Drupal's web forms with the ability to interact with them through RESTful APIs. With this module, developers can create, view, update, and delete web forms using HTTP requests, as well as manipulate form submission data.

Webform Rest expands the capabilities of Drupal 9, enabling integration with external applications such as CRM systems, email marketing services, mobile apps, and more. This integration facilitates the collection and utilization of web form data in other contexts, improving the efficiency and usability of your projects.

To use the Webform Rest module, we will follow the steps below:

1. Install the required modules.
2. Configure access permissions.
3. Configure CORS permissions (optional).
4. Format the request payload.
5. Make the requests.


## Requirements

To use Webform Rest in our application, we will need the following modules:

- Webform: for form creation.
- Rest UI: for permission configuration.
- Webform Rest: for the REST API of forms.


## Installing and Activating Webform Rest and Its Dependencies

In this case we are using Docker and [Lando](https://lando.dev/) as a solution for local development environments and manage Drupal's configurations via Composer. Therefore, we use the 'lando' command as a prefix in the commands below.


To install the module via Composer, run the following command in the CLI:

`$ lando composer require 'drupal/webform_rest:^4.0'`

To activate the module, run the following command in the CLI:

`$ lando drush en webform_rest`

For the configuration of Webform Rest, we also need to activate the Rest UI module to define access permissions.

`$ lando drush en restui`

You can also activate the modules via the Drupal administrative panel at `/admin/modules`.

## Configuring the Webform Rest Module

Now that the Webform Rest module is installed, let's start configuring the application's resources.

In `/admin/config/services/rest`, enable the "Webform submission," "Webform Elements," and "Webform Submit" resources.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jccrjt3ex0utpzsiqzph.png)


It is necessary to select at least one authentication method, in our case, "cookie".


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/099bokzde4bqq3uztesk.png)

To allow unauthenticated users on the site to submit requests through the form, it is necessary to enable the permission for 'Anonymous user' to make POST requests to the Webform Submit resource. This configuration can be found on the page `/admin/people/permissions`, in the "RESTful Web Services" section.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xhzz1f2qxkay3oewqnz1.png)


## A word about CORS

If you intend to make requests from a different domain than your application's installation, you will likely encounter a CORS issue like this:

![Browser console showing CORS error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijgl7ulw9ufhe1ioh6ki.jpg)

CORS, or Cross-Origin Resource Sharing, is a security policy implemented in web browsers to control requests between different origins (domains, ports, or protocols).

Simply put, CORS allows a server to restrict which resources can be accessed by a web application on a specific domain. Without the CORS policy, browsers enforce a policy called the "Same-Origin Policy," which restricts access to resources only from the same origin that provided them.

In Drupal 9, you can configure remote access permissions through the `services.yml` file in `cors.config` section. By default, this configuration is disabled.

> ⚠️ **Important**: For testing purposes, you can use the configuration below, which allows access from any type. However, it is crucial to exercise caution and avoid using this configuration in a production environment. It is not a recommended security practice and may result in access vulnerabilities to your application. Additionally, any third-party application will have permission to make requests to your API and create records in your form, which can be highly undesirable.


```
  cors.config:
	enabled: true
	# Specify allowed headers, like 'x-allowed-header'.
	allowedHeaders: ['x-csrf-token','authorization','content-type','accept','origin','x-requested-with', 'access-control-allow-origin','x-allowed-header','*']
	# Specify allowed request methods, specify ['*'] to allow all possible ones.
	allowedMethods: ['*']
	# Configure requests allowed from specific origins. Do not include trailing
	# slashes with URLs.
	allowedOrigins: ['*']
	# Sets the Access-Control-Expose-Headers header.
	exposedHeaders: false
	# Sets the Access-Control-Max-Age header.
	maxAge: false
	# Sets the Access-Control-Allow-Credentials header.
	supportsCredentials: true
```

In your local development environment, you probably have a file called `services.local.yml`. It is important to edit it with the above configuration, or it will override the configuration we made in `services.yml`.

After making this configuration, remember to clear the Drupal caches:
`$ lando drush cr`

Be very aware of the indentation in the YAML file and double-check if it is correct. I have spent a good amount of time debugging the application to understand why a configuration was not being reflected, only to find out that it was due to an incorrect indentation in the YAML file.


## Using the Webform Rest Module

To submit a form using Webform Rest, we simply need to make a **POST request** containing the necessary **headers** and **payload** to the /webform_rest/submit endpoint.

The request header should include 'Content-Type: application/json'.

An example request using Axios would look like this:

```
  const response = await axios.post('http://yoursite.lndo.site/webform_rest/submit', {
	"webform_id": "some_rest_form",
	"name": "Mario Zuany",
	"email": "teste@mario.com.br",
  }, {
	headers: {
  	"Content-Type": 'application/json',
	},
  });
```

This example demonstrates how to make a POST request using Axios, but you can use other HTTP libraries or frameworks to make the request as well.

The request payload consists primarily of the webform_id, which is the machine name of the target form, and its registered fields.

In our case, we have:

```
{
   "webform_id": "some_rest_form",
   "name": "Mario Zuany",
   "email": "foo@bar.com",
}
```

The response payload of a successful submission consists of the following fields:
- `sid`, the unique identifier of the recorded submission;
confirmation_type, the confirmation type (configurable in Webform),
- `confirmation_url`, the submission confirmation URL (configurable in Webform),
- `confirmation_message`, the confirmation message (configurable in Webform),
- `confirmation_title`, the title of the confirmation message (configurable in Webform).

In our case, we have:
```
{
   "sid": "bf9d4cf5-02b0-4d08-9355-40b97246346a",
   "confirmation_type": "inline",
   "confirmation_url": "",
   "confirmation_message": "Just a <strong>confirmation</strong> message",
   "confirmation_title": "A confirmation title"
}
```

Additionally, we also have access to validation messages generated by Webform itself. For example, if a required field is not submitted, we receive the following response:

```
{
   "message": "Submitted Data contains validation errors.",
   "error": {
       "email": "The email field is mandatory."
   }
}
```

With this information, we can handle the API response to provide users with confirmation messages, errors, etc.



## Wrapping up

The Webform Rest module in Drupal 9 provides a powerful way to integrate and interact with web forms using RESTful APIs. By allowing external applications to efficiently access and manipulate form data, this module extends the capabilities of Drupal 9 and opens doors to various integrations.

In this article, I have provided an overview of the Webform Rest module, detailed its configuration, and demonstrated how to use it to submit forms in Webform.

Since this is a general overview article, I have not covered other possibilities that can be explored with Webform Rest, such as updating submission records with PATCH, listing fields of a specific form with GET, and more. I plan to address these other topics in the future.

I hope this tutorial helps you make the most of the Webform Rest module in your Drupal 9 applications, making your projects even more flexible and integrated.

### References:

Here is a list of articles that helped me overcome some problems I faced when learning to use and configure Webform Rest.

- https://www.drupal.org/project/webform_rest
- https://www.learnwebtech.in/drupal9-submit-webform-data-using-rest-api-with-example/
- https://drupal.stackexchange.com/questions/310356/drupal-webform-rest
- https://www.drupalchamp.org/blog/how-create-webform-drupal-8-using-restful-web-services