Skip to content

Commit d959742

Browse files
committed
Deprecate update flag, update the docs
1 parent 3d55ae7 commit d959742

4 files changed

Lines changed: 37 additions & 7 deletions

File tree

src/Annotations/Input.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
use Attribute;
88
use RuntimeException;
99

10+
use function array_key_exists;
11+
12+
use const E_USER_DEPRECATED;
13+
1014
/**
1115
* The Input attribute must be put in a GraphQL input type class docblock and is used to map to the underlying PHP class
1216
* this is exposed via this input type.
@@ -33,6 +37,14 @@ public function __construct(
3337
string|null $description = null,
3438
bool|null $update = null,
3539
) {
40+
if ($update !== null || array_key_exists('update', $attributes)) {
41+
trigger_error(
42+
'Using #[Input(update: ...)] is deprecated and will be removed in a future major version. '
43+
. 'For partial updates, prefer nullable fields with Undefined to distinguish omitted values from explicit nulls.',
44+
E_USER_DEPRECATED,
45+
);
46+
}
47+
3648
$this->name = $name ?? $attributes['name'] ?? null;
3749
$this->default = $default ?? $attributes['default'] ?? $this->name === null;
3850
$this->description = $description ?? $attributes['description'] ?? null;
@@ -86,6 +98,8 @@ public function getDescription(): string|null
8698
/**
8799
* Returns true if this type should behave as update resource.
88100
* Such input type has all fields optional and without default value in the documentation.
101+
*
102+
* @deprecated Using #[Input(update: ...)] is deprecated; prefer nullable fields with Undefined.
89103
*/
90104
public function isUpdate(): bool
91105
{

tests/Annotations/InputTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,11 @@ public function testException(): void
1515
$this->expectExceptionMessage('Empty class for #[Input] attribute. You MUST create the Input attribute object using the GraphQLite AnnotationReader');
1616
(new Input())->getClass();
1717
}
18+
19+
public function testUpdateArgumentTriggersDeprecation(): void
20+
{
21+
$this->expectUserDeprecationMessageMatches('/Using #\[Input\(update: \.\.\.\)\] is deprecated/');
22+
23+
new Input(update: true);
24+
}
1825
}

website/docs/attributes-reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ Attribute | Compulsory | Type | Definition
178178
name | *no* | string | The name of the GraphQL input type generated. If not passed, the name of the class with suffix "Input" is used. If the class ends with "Input", the "Input" suffix is not added.
179179
description | *no* | string | Description of the input type in the documentation. If not passed, PHP doc comment is used.
180180
default | *no* | bool | Name of the input type represented in your GraphQL schema. Defaults to `true` *only if* the name is not specified. If `name` is specified, this will default to `false`, so must also be included for `true` when `name` is used.
181-
update | *no* | bool | Determines if the the input represents a partial update. When set to `true` all input fields will become optional and won't have default values thus won't be set on resolve if they are not specified in the query/mutation/subscription. This primarily applies to nullable fields.
181+
update | *no* | bool | Deprecated. `#[Input(update: true)]` still works for compatibility, but for partial updates you should prefer nullable fields with `Undefined` so omitted values can be distinguished from explicit `null`.
182182

183183
## #[Logged]
184184

website/docs/input-types.mdx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,8 @@ There are 2 input types added to the `UserInput` class: `CreateUserInput` and `U
151151
- Field `password` will appear for both. For `CreateUserInput` it'll be the required field and for `UpdateUserInput` optional.
152152
- Field `age` is optional for both input types.
153153

154-
Note that `update: true` argument for `UpdateUserInput`. It should be used when input type is used for a partial update,
155-
It makes all fields optional and removes all default values from thus prevents setting default values via setters or directly to public properties.
156-
In example above if you use the class as `UpdateUserInput` and set only `username` the other ones will be ignored.
157-
In PHP 7 they will be set to `null`, while in PHP 8 they will be in not initialized state - this can be used as a trick
158-
to check if user actually passed a value for a certain field.
154+
`update: true` is deprecated and will be removed in a future major version.
155+
For partial updates, prefer nullable fields with `Undefined` so you can distinguish omitted values from explicit `null`.
159156

160157
### Optional input fields
161158

@@ -201,12 +198,24 @@ class Article
201198
public function title(string|null|Undefined $locale): string
202199
{
203200
if ($locale === Undefined::VALUE) {
204-
return
201+
return $this->title;
205202
}
203+
204+
if ($locale === null) {
205+
throw new InvalidArgumentException('Locale cannot be null.');
206+
}
207+
208+
return $this->translateTitle($locale);
206209
}
207210
}
208211
```
209212

213+
For field parameters and input field properties, an explicit `= Undefined::VALUE` default is not required:
214+
when the type includes `Undefined`, GraphQLite resolves omitted values as `Undefined::VALUE`. Adding the
215+
default explicitly is optional and can still be useful for clarity. Constructor parameters and promoted
216+
properties are different: if you want an omitted value there to resolve to `Undefined::VALUE`, you still
217+
need a real PHP default such as `= Undefined::VALUE`.
218+
210219
## Factory
211220

212221
A **Factory** is a method that takes in parameter all the fields of the input type and return an object.

0 commit comments

Comments
 (0)