rebing/graphql-laravel
Code-first GraphQL integration for Laravel built on webonyx/graphql-php. Define schemas, types, queries and mutations in PHP with support for multiple schemas, middleware, resolver middleware, privacy rules, and n+1 avoidance via dataloaders or SelectFields.
## Technical Evaluation
### **Architecture Fit**
- **Code-first GraphQL**: Remains ideal for Laravel’s PHP-centric ecosystem, but **`SelectFields` is now a separate package** (`rebing/graphql-laravel-select-fields`), requiring explicit installation for Eloquent optimizations.
- **Schema Isolation**: Unchanged; multiple schemas still supported with independent middleware.
- **Middleware Layers**: Enhanced with `ResolverParameterInjector` for **custom dependency injection (DI) hooks** in resolvers, expanding flexibility for complex logic.
- **Data Loading Strategies**:
- **Dataloaders**: Still available for batching (e.g., external APIs).
- **SelectFields**: **Now optional** (extracted to separate package). Teams must explicitly install `rebing/graphql-laravel-select-fields` for Eloquent optimizations (`select()`, `with()`).
- **Hybrid Approach**: Still supported, but requires deliberate package selection.
- **Observability**: OpenTelemetry support remains, but **no changes** in RC4. Security hardening in RC1 (e.g., stricter defaults for `query_max_depth`, `query_max_complexity`) improves production safety.
### **Integration Feasibility**
- **Laravel Ecosystem Synergy**:
- **Validation**: Unchanged; Laravel rules still work in queries/mutations.
- **Authorization**: **Stricter defaults** in RC1 (`=== true` comparison, runs before validation).
- **Testing**: Orchestra Testbench compatibility remains, but **`SelectFields` boilerplate is no longer auto-generated** in stubs.
- **Artisan Generators**: Updated to **omit `SelectFields` by default** (must be added manually if needed).
- **Database Compatibility**:
- Eloquent integration **requires explicit `rebing/graphql-laravel-select-fields`** installation.
- Raw SQL/custom resolvers remain supported.
- **Frontend Agnostic**: Unchanged; works with any GraphQL client.
### **Technical Risk**
| **Risk Area** | **Mitigation** |
|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Performance Overhead** | - Use **Dataloaders** for external APIs.<br>- Enable `AutomaticPersistedQueries` to cache queries.<br>- Monitor with OpenTelemetry.<br>- **Explicitly install `SelectFields`** for Eloquent optimizations. |
| **Schema Evolution** | - Backward-compatibility checks via `roave/backward-compatibility-check`.<br>- **Deprecate fields** using `@deprecated` directives.<br>- Use interfaces/unions for extensibility.<br>- **RC4 breaks `SelectFields` integration** (now separate package). |
| **Complexity Management** | - Split schemas for large APIs.<br>- Use **`ResolverParameterInjector`** for custom DI in resolvers.<br>- Leverage middleware for isolation.<br>- **Avoid `SelectFields` if not needed** to reduce dependencies. |
| **Security** | - **RC1 hardens defaults**: POST-only, disabled introspection, `query_max_depth=13`, `query_max_complexity=500`.<br>- Enforce `AuthorizationError` for access control.<br>- **RC4 fixes APQ race condition** (TOCTOU). |
| **Migration Path** | - **RC4 requires explicit `SelectFields` package** for Eloquent optimizations.<br>- Start with a single schema; refactor into multiple schemas as needed.<br>- Use `graphql:schema` middleware for routing. |
| **Vendor Lock-in** | - Underlying `webonyx/graphql-php` remains reference implementation.<br>- **MIT license allows forks**, but `SelectFields` extraction increases modularity.<br>- Avoid package-specific features if portability is critical. |
### **Key Questions for TPM**
1. **Schema Strategy**:
- Will the API use **`SelectFields` for Eloquent optimizations**? If yes, will the team install the separate package (`rebing/graphql-laravel-select-fields`)?
- How will schema evolution (deprecations, breaking changes) be managed, especially with **`SelectFields` now optional**?
2. **Data Loading**:
- Are most queries Eloquent-based (**requires `SelectFields`**) or external API calls (**use Dataloaders**)?
- Will custom resolvers leverage the new **`ResolverParameterInjector`** for DI hooks?
3. **Performance**:
- Are the **new security defaults** (e.g., `query_max_depth=13`) acceptable, or should they be adjusted?
- Will persisted queries be enabled to reduce parsing overhead?
4. **Security**:
- Should introspection remain disabled in production?
- Are there sensitive fields requiring **strict authorization** (now runs before validation)?
5. **Observability**:
- Will OpenTelemetry tracing be enabled for all schemas or selectively?
- Are there third-party tools (e.g., Datadog) that need integration?
6. **Team Skills**:
- Does the team have experience with GraphQL, or will training be required for **new DI hooks** and **optional `SelectFields`**?
- Will frontend teams need GraphiQL for development?
7. **Testing**:
- Will database-backed tests (`TestCaseDatabase`) be used for Eloquent queries (**now requires `SelectFields`**)?
- Are there plans for automated query validation?
---
## Integration Approach
### **Stack Fit**
- **Laravel 12/13**: Native support with zero framework conflicts.
- **PHP 8.2+**: Leverages modern features (attributes, strict typing).
- **Dependencies**:
- **Core**: `webonyx/graphql-php` (reference implementation).
- **Optional**:
- `rebing/graphql-laravel-select-fields` (**new in RC4**) for Eloquent optimizations.
- `open-telemetry/api` (tracing).
- `mll-lab/laravel-graphiql` (IDE).
- **Frontend**: Agnostic; works with Apollo Client, Relay, or custom fetch calls.
### **Migration Path**
| **Phase** | **Actions** |
|-------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Evaluation** | - Install **core package** (`composer require rebing/graphql-laravel`).<br>- **Decide if `SelectFields` is needed** (install separately if Eloquent optimizations are required).<br>- Test with a simple query/mutation. |
| **Pilot Schema** | - Define a single schema with 3–5 queries/mutations.<br>- **If using Eloquent**: Install `rebing/graphql-laravel-select-fields` and add `SelectFields` manually to types.<br>- Enable GraphiQL for frontend testing. |
| **Multi-Schema Rollout**| - Split schema into `public`, `admin`, or `v1`/`v2`.<br>- Use `graphql:schema` middleware to route requests (e.g., `/graphql/admin`). |
| **Optimization** | - Profile with OpenTelemetry to identify slow resolvers.<br>- Add **Dataloaders** for external APIs.<br>- Enable persisted queries for high-traffic endpoints.<br>- **Leverage `ResolverParameterInjector`** for custom DI. |
| **Production Readiness**| - **RC1 security defaults**: Disable introspection, set `query_max_depth`, and `query_max_complexity`.<br>- Configure error formatting for client safety.<br>- **RC4 fixes**: Verify APQ middleware stability. |
### **Compatibility**
- **Laravel Features**:
- ✅ Eloquent models (**requires `rebing/graphql-laravel-select-fields`**).
- ✅ Validation (Laravel rules in `args()`).
- ✅ Middleware (HTTP and GraphQL execution).
- ✅ Authentication (Laravel gates/policies in `authorize()`).
- ✅ Testing (Testbench, fixtures).
- **Limitations**:
- ❌ **`SelectFields` no longer auto-included** (must be installed separately).
- ❌ Subscriptions (use Laravel Broadcasting or Lighthouse).
- ❌ File uploads require custom scalar types.
- ❌ No built-in caching layer (use Laravel’s cache or Redis for query results).
### **Sequencing**
1. **Setup**:
- Install **core package** and publish config (`php artisan vendor:publish --provider="Rebing\GraphQL\GraphQLServiceProvider"`).
- **Decide on `SelectFields`**: Install `rebing/graphql-laravel-select-fields` if Eloquent optimizations are needed.
- Configure `config/graphql.php` (schemas, middleware, **RC1 security defaults**).
2. **Core Schema**:
- Generate types/queries with Artisan (`make:graphql:type`, `make:graphql:query`).
- **If using `SelectFields`**: Manually add `use Rebing\GraphQL\Laravel\SelectFields;` and configure in types.
3. **Validation/Authorization**:
- Add `rules()` to queries/mutations.
- Implement `authorize()` for sensitive fields (**now runs before validation**).
4. **Performance**:
- Add **Dataloaders** for external APIs.
- Enable persisted queries.
- **Leverage `ResolverParameterInjector`** for custom resolver
How can I help you explore Laravel packages today?