mll-lab/graphql-php-scalars
Custom scalar types for webonyx/graphql-php, including BigInt, Date/DateTime/DateTimeTz, Email, JSON, and IntRange for bounded integers. Drop-in types for schema definitions with strict parsing and DateTimeImmutable conversion for date scalars.
Start by installing the package via Composer:
composer require mll-lab/graphql-php-scalars
Then, import and register the scalars you need in your GraphQL schema definition. For example, to use DateTimeScalar and UuidScalar in a schema built with webonyx/graphql-php:
use MLL\GraphQLScalars\Scalars\DateTimeScalar;
use MLL\GraphQLScalars\Scalars\UuidScalar;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Schema;
$typeMap = [
'DateTime' => new DateTimeScalar(),
'UUID' => new UuidScalar(),
];
// Then reference them in your schema type definitions by name ('DateTime', 'UUID')
$queryType = new ObjectType([
'name' => 'Query',
'fields' => [
'user' => [
'type' => $typeMap['UUID'], // or use string keys if your schema builder supports it
'args' => [
'id' => ['type' => 'UUID'],
],
],
],
]);
$schema = new Schema(['query' => $queryType, 'typeMap' => $typeMap]);
The README is your first stop—list all available scalars (e.g., Email, Url, PositiveInt, JsonString) and their validation rules.
Centralized Scalar Registry: Create a dedicated GraphQLScalars service or config file to define and reuse scalars across multiple schemas (e.g., monolith vs. microservices), ensuring consistency:
// config/graphql-scalars.php
return [
' scalars' => [
'Email' => new EmailScalar(),
'UtcDateTime' => (new DateTimeScalar())->setTimezone('UTC'),
],
];
Framework Integration: In Lighthouse (Laravel), register scalars in config/lighthouse.php via the scalars key—this package has first-class support. For custom implementations or Apollo Federation, use TypeRegistry::registerScalar() or pass scalars in the typeMap.
Timezone-Aware DateTimes: For DateTimeScalar, inject custom timezone preferences in your service binding to avoid inconsistent parsing between services:
new DateTimeScalar(timezone: new \DateTimeZone('America/New_York'))
Validation Enforcement: Leverage built-in validation in parseLiteral() and parseValue()—they throw InvalidValueError or ValidationError with clear messages, enabling consistent error responses.
Schema Builder Compatibility: If using a code-first schema builder (e.g., Nuwave/Lighthouse or hand-built), ensure the scalar names match the keys used in TypeRegistry or typeMap. Mismatches cause Undefined type errors at runtime.
Default Timezone Pitfall: DateTimeScalar defaults to UTC. If your app runs in a different timezone, explicitly configure the timezone and ensure incoming strings conform (e.g., 2023-01-01T12:00:00Z). Use parseLiteral() for custom parsing logic only if absolutely necessary.
Null Handling: Scalars accept null by default unless wrapped in NonNull. Use NonNull::make($scalar) in your field definitions for strict non-null constraints.
Extending Scalars: Extend base scalars like DateTimeScalar to override serialize()/parseValue() for domain-specific formatting (e.g., ISO 8601 without milliseconds), but avoid bypassing validation unless necessary.
Testing: Write unit tests for your scalar usages (especially parseLiteral() for introspected queries) and integration tests verifying invalid input returns expected GraphQL errors. The package uses \GraphQL\Error\Error-compatible exceptions, so debug with debug(), xdebug_break(), or logging in parseLiteral().
Latest Release Date: Note the release date (2025-06-30) is in the future—verify actual latest release via Composer to avoid stale info. If outdated, check for forks or consider if the core feature set is stable.
How can I help you explore Laravel packages today?