
Building Headless + Decoupled Drupal 10 APIs

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 👇