rebing/graphql-laravel
Code-first GraphQL integration for Laravel based on webonyx/graphql-php. Define schemas, types, queries and mutations in PHP. Supports multiple schemas, per-schema middleware, resolver middleware, and n+1 prevention via dataloaders or SelectFields eager loading.
## Technical Evaluation
### **Architecture Fit**
- **Code-First GraphQL**: Aligns perfectly with Laravel’s object-oriented paradigm, enabling schema definition via PHP classes (Types, Queries, Mutations) rather than `.graphql` files. This reduces context-switching for backend developers and integrates seamlessly with Laravel’s dependency injection and service container.
- **Schema Isolation**: Supports **multiple schemas** (e.g., `default`, `admin`, `public`), each with independent queries, mutations, types, and middleware. This is ideal for:
- **Multi-tenancy** (e.g., tenant-specific GraphQL APIs).
- **Feature flags** (e.g., experimental schemas behind auth gates).
- **Microservices** (e.g., aggregating schemas from multiple Laravel services).
- **Middleware Layers**:
- **Execution Middleware**: Global pipeline for cross-cutting concerns (e.g., auth, tracing, persisted queries). Example: `ValidateOperationParamsMiddleware` or `AutomaticPersistedQueriesMiddleware`.
- **Resolver Middleware**: Per-field middleware for granular control (e.g., logging, caching, or auditing specific resolvers).
- **Data Loading Strategies**:
- **Dataloaders**: Deferred resolution to batch database queries (critical for avoiding N+1 queries with Eloquent).
- **SelectFields**: Optimizes Eloquent queries by analyzing GraphQL selections to generate `select()` and `with()` clauses. Reduces over-fetching and improves performance.
- **Observability**: Built-in **OpenTelemetry** support for tracing GraphQL operations (per-field or per-schema). Essential for debugging complex queries in production.
### **Integration Feasibility**
- **Laravel 12/13 Compatibility**: Explicitly supports Laravel 12.x–13.x with PHP 8.2+. Leverages Laravel’s:
- **Service Provider**: Auto-registers routes (`/graphql`), config, and commands.
- **Artisan Generators**: 12 scaffolding commands (e.g., `make:graphql:query`, `make:graphql:mutation`) to accelerate development.
- **Validation**: Native Laravel validation rules for GraphQL arguments (e.g., `rules()` method on queries/mutations).
- **Eloquent Integration**:
- **SelectFields**: Transparently optimizes Eloquent queries based on GraphQL field selections.
- **Dataloaders**: Works with any data source (e.g., Eloquent, API clients) via `webonyx/graphql-php`'s deferred resolution.
- **Security**:
- **Introspection**: Disabled by default (enable via `.env` for dev).
- **Query Depth/Complexity**: Configurable limits to prevent DoS attacks.
- **Authorization**: Per-field/mutation/query `authorize()` methods or middleware (e.g., `AddAuthUserContextValueMiddleware`).
- **Testing**: Built-in test helpers (`TestCase`, `TestCaseDatabase`) and fixtures (e.g., `User`, `Post` models) for unit and integration tests.
### **Technical Risk**
| **Risk Area** | **Mitigation** |
|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Performance Overhead** | - Use `SelectFields` for Eloquent to avoid N+1 queries. <br> - Benchmark with `webonyx/graphql-php`'s [performance guide](https://github.com/webonyx/graphql-php#performance). <br> - Enable persisted queries. |
| **Schema Complexity** | - Start with a single schema; split into multiple schemas as needed. <br> - Use `graphql:schemaConfig` generator for schema-specific configs. |
| **Middleware Conflicts** | - Test execution middleware order (later middleware can override earlier). <br> - Use `graphql.execution_middleware` config to explicitly define pipeline. |
| **Migration from REST** | - Gradually replace REST endpoints with GraphQL queries/mutations. <br> - Use Laravel’s route middleware to gate access (e.g., `throttle:api`). |
| **Vendor Lock-in** | - Underlying `webonyx/graphql-php` is a reference implementation. <br> - Schema defined in PHP classes (not `.graphql` files) reduces lock-in. |
| **Real-Time Requirements** | - Subscriptions not supported; use Laravel Broadcasting + WebSockets or [Lighthouse](https://lighthouse-php.com/) for real-time features. |
### **Key Questions**
1. **Schema Design**:
- How will we structure schemas (e.g., per-tenant, per-feature)?
- Do we need **multiple schemas** or can a single schema suffice?
2. **Data Loading**:
- Will we use **Dataloaders** (for complex batching) or **SelectFields** (for Eloquent optimization)?
- Are there legacy APIs or external services requiring custom dataloaders?
3. **Performance**:
- What are the expected query depths/complexities? (Configure `graphql.query_depth_limit`.)
- Should we enable **persisted queries** to reduce parsing overhead?
4. **Security**:
- Are there sensitive fields requiring **privacy/authorization** rules?
- Should introspection be disabled in production?
5. **Observability**:
- Do we need **OpenTelemetry tracing** for debugging complex queries?
6. **Testing**:
- Will we use the built-in `TestCaseDatabase` for Eloquent-based tests?
- Do we need custom test fixtures or mocks?
7. **Migration**:
- How will we phase out REST endpoints in favor of GraphQL?
- Will we use **GraphQL as a replacement** or **alongside REST** (e.g., for mobile clients)?
---
## Integration Approach
### **Stack Fit**
- **Laravel Ecosystem**:
- **Service Provider**: Auto-registers routes, config, and commands. No manual setup beyond `composer require` and `php artisan vendor:publish`.
- **Artisan Generators**: Accelerates development with 12 scaffolding commands (e.g., `make:graphql:mutation`).
- **Validation**: Native Laravel validation rules (e.g., `rules()` method) for GraphQL arguments.
- **Testing**: Built-in `TestCase` and `TestCaseDatabase` for unit/integration tests.
- **PHP/GraphQL**:
- **Code-First**: Schema defined in PHP classes (Types, Queries, Mutations) aligns with Laravel’s OOP style.
- **webonyx/graphql-php**: Underlying implementation is a reference GraphQL spec port, ensuring compatibility with tools like GraphiQL.
- **Dataloaders**: Leverages `webonyx/graphql-php`'s deferred resolution for batching (critical for performance).
- **Database**:
- **Eloquent Integration**: `SelectFields` optimizes queries by analyzing GraphQL selections for `select()` and `with()`.
- **Raw SQL**: Works with any data source (e.g., PostgreSQL, MySQL, APIs) via custom dataloaders.
### **Migration Path**
1. **Assessment Phase**:
- Audit existing REST endpoints to identify candidates for GraphQL replacement.
- Define schema boundaries (e.g., per-module, per-tenant).
2. **Pilot Schema**:
- Start with a **single schema** (e.g., `default`) and a few critical queries/mutations.
- Use `make:graphql:query` and `make:graphql:mutation` to scaffold endpoints.
3. **Incremental Rollout**:
- **Phase 1**: Replace read-heavy REST endpoints with GraphQL queries.
- Example: Convert `GET /api/users` → `{ users { id name email } }`.
- **Phase 2**: Replace write endpoints with mutations.
- Example: Convert `POST /api/users` → `mutation { createUser(input: { name: "John" }) { id } }`.
- **Phase 3**: Optimize with `SelectFields` and dataloaders.
4. **Deprecation**:
- Use Laravel middleware to **deprecate REST endpoints** (e.g., `header('X-Deprecated: true')`).
- Gradually remove REST routes as GraphQL adoption grows.
### **Compatibility**
| **Component** | **Compatibility** |
|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Laravel** | Explicitly supports Laravel 12.x–13.x. Uses Laravel’s service container, validation, and testing tools. |
| **Eloquent** | `SelectFields` optimizes queries; dataloaders work with any Eloquent model. |
| **API Clients** | Works with any GraphQL client (e.g., Apollo, Relay, GraphiQL). Supports persisted queries for reduced payload size. |
| **Third-Party Packages** | - **GraphiQL**: Install `mll-lab/laravel-graphiql` for an IDE-like interface. <br> - **OpenTelemetry**: Add `open-telemetry/api` for tracing. <br> - **Lighthouse**: For subscriptions (if needed). |
| **Existing Code** | - REST controllers can coexist with GraphQL routes. <br> - Use Laravel’s route middleware to gate access (e.g., `throttle:api`). |
### **Sequencing**
How can I help you explore Laravel packages today?