Building Headless + Decoupled Drupal 10 APIs

Building Headless + Decoupled Drupal 10 APIs

Building Headless + Decoupled Drupal 10 APIs
Anandaakrishnan G A
19 April, 2025

At Arudhra IT Techs, we build headless Drupal backends for everything — from mobile apps to JS frontends. This blog shows how we create secure JSON APIs in Drupal 10 using custom routes, controller classes, and OAuth2 token authentication.

Building Headless + Decoupled Drupal 10 APIs with OAuth2, Custom Controllers & JSON Output

Drupal 10 is no longer just a CMS — it’s a powerful API backend. With the right architecture, we can build fully headless applications that serve JSON to React, Vue, Flutter, or native apps. Here’s how we do it using custom controllers and OAuth2.

🚀 Step 1: Create a Custom Module

Start by generating your module. We'll call it custom_api.

drupal generate:module

🔁 Step 2: Define a Custom API Route

Create custom_api.routing.yml:


custom_api.user_data:
  path: '/api/user/{uid}'
  defaults:
    _controller: '\Drupal\custom_api\Controller\UserApiController::getUserData'
    _format: 'json'
  requirements:
    _permission: 'access content'
    uid: \d+
  options:
    _auth: ['oauth']
    no_cache: 'TRUE'
    expose: TRUE
    _format: 'json'
    parameters:
      uid:
        type: integer
    

📦 Step 3: Build the Controller

File: src/Controller/UserApiController.php


namespace Drupal\custom_api\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Drupal\user\Entity\User;
class UserApiController {
  public function getUserData($uid) {
    $account = User::load($uid);
    if (!$account) {
      return new JsonResponse(['error' => 'User not found'], 404);
    }
    return new JsonResponse([
      'uid' => $account->id(),
      'name' => $account->getDisplayName(),
      'email' => $account->getEmail(),
    ]);
  }
}
    

🔐 Step 4: Secure the API with OAuth2 (Simple OAuth)

Install Simple OAuth and dependencies:


composer require drupal/simple_oauth
drush en simple_oauth key_auth
    

Generate tokens:

/oauth/token (POST)

Pass tokens in headers:

Authorization: Bearer your_token_here

This ensures only authenticated clients can access your JSON APIs.

🔄 Optional: REST UI + JSON:API?

If you prefer out-of-the-box:

  • Enable jsonapi module
  • Enable REST UI module

But for true flexibility — we prefer custom routes like above.

🔍 Real Use Case: Flutter App Backend

  • 📱 Mobile app fetches user + orders from Drupal via JSON
  • 🔐 Uses OAuth2 to validate every call
  • 🧾 Laravel handles payments, but Drupal stores content

All decoupled, secure, and fast 🔥

Need a Drupal JSON API for Your Mobile or JS Frontend?

We build custom, secure Drupal APIs with OAuth2, JSON responses, and decoupled logic. Perfect for SPAs, React, Vue, or native apps.

Let’s build your backend powerhouse 👇

Get API Help from Drupal Experts