Entity Gateway provides a configurable REST API for exposing selected Drupal entities and fields to external applications. Administrators can choose which entity types, bundles, and fields to make available, and the module automatically expands entity reference fields for easier consumption. It offers built-in filtering capabilities and is designed for projects where Drupal serves as a content backend with a need for simpler, structured JSON representations.
Entity Gateway turns the Drupal content entity types and bundles you choose into read/write JSON REST resources under /api/..., for frontend applications, mobile apps and integrations.
Nothing is exposed by default. For each bundle, administrators pick the HTTP methods and the individual fields โ and that one field list controls what can be read, filtered, sorted and written. Responses are plain JSON with camelCase keys and no per-entity metadata envelope, so consumers do not need to know Drupal's data model.
Features
- Opt-in resources: Choose entity types, bundles, HTTP methods (
GET,POST,PATCH,DELETE) and fields per bundle. Any content entity type works, custom ones included. - Predictable endpoints:
/api/nodelists every bundle of an entity type in one response,/api/node/articlenarrows it to one bundle, and/api/node/article/{uuid}reads, updates or deletes a single entity. Entities are always addressed by UUID. - Per-field output formats: Each field's JSON shape comes from a field output plugin, much like Manage display: formatted text run through its text format, dates in any Drupal date format, path aliases, file URLs and image style URLs.
- Relationships your way: A reference field returns the referenced UUID (the default), its ID, the UUID with a label, or the whole referenced entity inlined. Inlining is bounded by a site-wide max inline depth (default 2), which a field may lower but never raise.
- Filtering, sorting and pagination:
?filter[created][gte]=...,?sort=-created,titleand?page=2&perPage=25, restricted to the fields the resource exposes. - Writes:
POSTcreates,PATCHchanges only the keys you send,DELETEremoves. A rejected write returns a 422 with a per-field error map and saves nothing. - Nested creation: A reference field can opt in to creating the referenced entities in the same request (a product with its variations, an article with its paragraphs). The whole request is atomic and bounded by site-wide depth and entity-count limits.
- File uploads: Every exposed file or image field gets an upload route and an upload-and-attach route, validated against the field's own settings.
- Access and caching: Entity and field access is checked for the current user on every read and write. Read responses carry the cache tags of every entity they include, so an edit invalidates them.
- Languages: The API serves the content language Drupal negotiated (URL prefix, domain,
Accept-Language), falls back to the closest existing translation and reports it inContent-Language. - Extensible: Other modules add field output and field input plugins with a PHP attribute โ no normalizer priorities to manage โ and subscribe to Symfony events around every write (access, prepare, validate, completed) to override or extend it per resource.
An example collection response, from GET /api/commerce_product?perPage=2:
{ "total": 128, "page": 1, "perPage": 2, "count": 2, "data": [ { "uuid": "744a1c3c-abed-40b4-a40e-764c470e7fce", "type": "pizza", "title": "Margherita", "diameterCm": 32 }, { "uuid": "9f1c1c2e-3a2b-4f9e-8b1a-1c2e3a2b4f9e", "type": "drink", "title": "Sparkling water", "volumeMl": 500 } ] }
Submodules
All optional. The API behaves the same with or without them.
- Entity Gateway UI (
entity_gateway_ui): The admin screens for settings, resources and fields, plus a dashboard of every generated route. Without it, configure resources with a config import ordrush config:set. - Entity Gateway OpenAPI (
entity_gateway_openapi): An OpenAPI 3.1 document at/api/openapi.jsonand/api/openapi.yaml, generated from the live configuration with a read and a write schema per resource, and a Swagger UI page to try every endpoint from the browser. - Entity Gateway Media (
entity_gateway_media): Reads a media reference as original and image style URLs, with a configurable fallback for non-image media. Writes can create media from a nested object, or from a bare URL for oEmbed media types such as remote video. - Entity Gateway Translation (
entity_gateway_translation): LetsPATCHcreate a translation that does not exist yet andDELETEremove a single translation, following Drupal's content translation permissions. - Entity Gateway User (
entity_gateway_user): Lets an anonymous visitor register an account throughPOST /api/user, following the site's own account settings (who can register, email verification, administrator approval). Nothing to configure beyond exposing theuserresource withPOST.
Integrations
- Entity Gateway Commerce: Adds a
commerce_priceoutput format that returns price fields as{number, currency_code, formatted}, formatted for the request's locale. Nested creation lets a client post a product together with its variations. Requires Commerce 3. - Paragraphs: Paragraph fields (
entity_reference_revisions) work like any other reference. Configure a paragraph type's fields without enabling any HTTP method, and its paragraphs are inlined into their host without getting endpoints of their own. With nested creation, a client creates the host and its paragraphs in one request, choosing each paragraph type with thebundlekey. This also requiresPOSTon the paragraph type's resource. - Media and Image (core): Image fields return original and image style URLs out of the box. Media references do the same with the Entity Gateway Media submodule, without having to configure the media type as a resource.
- Content Translation (core): Reads and writes follow Drupal's language negotiation. Creating and deleting single translations needs the Entity Gateway Translation submodule.
Configuration
No Drupal content is exposed by default. The screens below are provided by the Entity Gateway UI submodule and require the administer entity gateway permission.
1. Settings
Go to /admin/config/services/entity-gateway to choose the authentication providers the API accepts and set the max inline depth, the nested write limits and debug mode.
2. Resources
Go to /admin/config/services/entity-gateway/resource-list and open an entity type. For each bundle:
- enable the HTTP methods the bundle should accept;
- choose the visible fields โ a bundle needs at least one before it publishes any endpoint;
- optionally override a field's JSON key, and pick its output format and input plugin.
A field that references another bundle stays blocked until that bundle has fields of its own configured, so a relationship never serializes to nothing.
3. Consume the API
GET /api/{entity_type}, GET /api/{entity_type}/{bundle} and GET /api/{entity_type}/{bundle}/{uuid}, for example GET /api/node/article. On a cookie session, every non-GET request needs an X-CSRF-Token header, from /session/token.
Resource configuration changed outside the admin UI (config import, drush config:set) takes effect after a cache rebuild.
Administrators should expose only the entities and fields that API consumers need.
Authentication
Entity Gateway does not provide authentication of its own. It only chooses which of Drupal's authentication providers its routes accept (the Authentication providers setting; every enabled provider by default) and enforces the CSRF header on cookie sessions exactly as core does. Use one of:
- Session cookie (core):
POST /user/login?_format=jsonwith{"name": "...", "pass": "..."}sets the session cookie and returns acsrf_token;POST /user/logout?_format=json&token=...ends it. The natural choice for a front end served from the same domain. - HTTP Basic (core
basic_authmodule): anAuthorization: Basicheader on every request. - Tokens for decoupled front ends: any community module that registers an authentication provider works unchanged, such as Simple OAuth (OAuth 2.0 bearer tokens) or JSON Web Token Authentication. Token requests carry no session, so they need no CSRF header.
Account registration is covered by the Entity Gateway User submodule; password reset requests, login status and logout are core's own JSON endpoints, listed in the client guide.
Requirements
Drupal 10.3 or later, or Drupal 11, on PHP 8.3 or later.
The core Serialization module, enabled automatically as a dependency.
No contributed modules or PHP libraries are required. The Swagger UI page of the optional OpenAPI submodule loads swagger-ui-dist from the jsDelivr CDN.
Filtering, sorting and pagination
Equality
GET /api/node/article?filter[status]=1
With an operator
GET /api/node/article?filter[created][gte]=1700000000&filter[created][lte]=1750000000
Several operators under the same field are combined with AND, which is how you express a range.
Lists
GET /api/node/article?filter[category][in]=desserts,pizza,salads
A comma in the equality form is a literal character; use in or notIn for lists.
Supported operators:
eq,ne,gt,gte,lt,ltein,notIncontains,startsWith,endsWith,likenull
Field names are the same keys the JSON response uses: camelCase, without the field_ prefix. filter[category] filters field_category.
Entity reference fields are filtered by the referenced entity's UUID:
GET /api/node/article?filter[category]=d0f7a6a0-9a2e-4c83-9d9a-111122223333
Sorting
GET /api/node/article?sort=-created,title
A - prefix sorts descending.
Pagination
GET /api/node/article?page=2&perPage=25
perPage defaults to 10 and is capped at 50.
Only fields the resource exposes can be filtered or sorted. An unknown operator, an unexposed field or a malformed value returns HTTP 400 Bad Request.
The full query reference is in docs/querying.md. The client guide, docs/api-guide.md, covers response shapes, writes, uploads, translations and the error catalogue.
Similar projects
Drupal core JSON:API
JSON:API is the recommended choice when consumers need the standardized JSON:API specification.
Entity Gateway focuses on plain JSON responses, explicit per-field exposure, configurable per-field output formats, relationships that can be inlined, and nested writes.
Drupal core REST
Drupal core REST provides the foundation for building REST APIs.
Entity Gateway focuses on exposing selected entity data through configuration, without writing a custom REST resource for each endpoint.
Contributing
Entity Gateway is an open source Drupal project. Bug reports, testing, documentation improvements, patches, merge requests, and API use-case suggestions are welcome.
Site configuration is covered in the README, API consumers are covered in docs/api-guide.md, and setting up a development environment and running the test suites is covered in CONTRIBUTING.md.
Built by a human using an AI assistant: ๐ค โ ๐งParts of this module were generated with AI coding agents under human supervision.
Depends on
Dependencies of the latest stable release
No dependencies recorded for this project.
Required by
Tracked projects that depend on this one
No tracked projects depend on this one yet.
More in the Entity ecosystem
Most installed first
Activity
Release Timeline
Releases
| Version | Type | Core | Release date | |
|---|---|---|---|---|
| 1.0.0-beta2 | Pre-release | 10โ11 | Sep 14, 2026 | |
| 1.0.0-beta1 | Pre-release | 10โ11 | Sep 13, 2026 | |
| 1.0.x-dev | Dev | 10โ11 | Aug 10, 2026 |