{"id":20111923,"url":"https://github.com/graphpql/graphpinator-constraint-directives","last_synced_at":"2025-05-06T11:31:31.512Z","repository":{"id":36973458,"uuid":"336769634","full_name":"graphpql/graphpinator-constraint-directives","owner":"graphpql","description":":zap::globe_with_meridians::zap: Typesystem directives to declare additional validation on top of GraphQL type system.","archived":false,"fork":false,"pushed_at":"2024-11-01T04:08:12.000Z","size":606,"stargazers_count":3,"open_issues_count":6,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-01T08:18:33.294Z","etag":null,"topics":["graphql","graphql-php","php"],"latest_commit_sha":null,"homepage":"https://github.com/graphpql","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/graphpql.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-07T11:27:39.000Z","updated_at":"2024-08-26T07:39:53.000Z","dependencies_parsed_at":"2023-02-17T02:00:40.472Z","dependency_job_id":"5d570e57-cbea-4e4b-abbe-3da81bced7d6","html_url":"https://github.com/graphpql/graphpinator-constraint-directives","commit_stats":null,"previous_names":["graphpql/graphpinator-constraint-directives","infinityloop-dev/graphpinator-constraint-directives"],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphpql%2Fgraphpinator-constraint-directives","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphpql%2Fgraphpinator-constraint-directives/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphpql%2Fgraphpinator-constraint-directives/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphpql%2Fgraphpinator-constraint-directives/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/graphpql","download_url":"https://codeload.github.com/graphpql/graphpinator-constraint-directives/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224499991,"owners_count":17321615,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graphql","graphql-php","php"],"created_at":"2024-11-13T18:18:12.748Z","updated_at":"2024-11-13T18:18:13.194Z","avatar_url":"https://github.com/graphpql.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GraPHPinator Constraint directives [![PHP](https://github.com/graphpql/graphpinator-constraint-directives/actions/workflows/php.yml/badge.svg)](https://github.com/graphpql/graphpinator-constraint-directives/actions/workflows/php.yml) [![codecov](https://codecov.io/gh/infinityloop-dev/graphpinator-constraint-directives/branch/master/graph/badge.svg)](https://codecov.io/gh/infinityloop-dev/graphpinator-constraint-directives)\n\n:zap::globe_with_meridians::zap: Typesystem directives declare additional validation on the top of the GraphQL type system.\n\n## Introduction\n\nThis package allows server to declare additional constraints on accepted values for arguments, fields and input fields. It is also possible for client to declare constraints for variables in request document.\n\nAdditional benefit of using constraint directives is that expected values are displayed to client using GraphQL type language in a self-documenting manner.\n\n## Installation\n\nInstall package using composer\n\n```composer require infinityloop-dev/graphpinator-constraint-directives```\n\n## How to use\n\nIn order to enable constraint directives on your server, the only thing you need to do is to put selected directives to your `Container`. To avoid cyclic dependencies `ConstraintDirectiveAccessor` must be implemented. This step should be automated when using a DI solution.\n\nHere is example configuration for Nette DI:\n```neon\n- Graphpinator\\ConstraintDirectives\\StringConstraintDirective\n- Graphpinator\\ConstraintDirectives\\IntConstraintDirective\n- Graphpinator\\ConstraintDirectives\\FloatConstraintDirective\n- Graphpinator\\ConstraintDirectives\\ListConstraintDirective\n- Graphpinator\\ConstraintDirectives\\ObjectConstraintDirective\n- Graphpinator\\ConstraintDirectives\\ListConstraintInput\n- Graphpinator\\ConstraintDirectives\\ConstraintDirectiveAccessor(\n    string: Graphpinator\\ConstraintDirectives\\StringConstraintDirective\n    int: Graphpinator\\ConstraintDirectives\\IntConstraintDirective\n    float: Graphpinator\\ConstraintDirectives\\FloatConstraintDirective\n    list: Graphpinator\\ConstraintDirectives\\ListConstraintDirective\n    object: Graphpinator\\ConstraintDirectives\\ObjectConstraintDirective\n    listInput: Graphpinator\\ConstraintDirectives\\ListConstraintInput\n)\n```\n\n### Add constraint to Argument\n\nThe most common usage of constraint directives is to validate input from client without having to do it yourself in the resolve function.\n\n```php\n$intConstraint; // instance of \\Graphpinator\\ConstraintDirectives\\IntConstraintDirective\n\n\\Graphpinator\\Typesystem\\Argument\\Argument::create(\n    'year'\n    \\Graphpinator\\Typesystem\\Container::Int(),\n)-\u003eaddDirective(\n    $intConstraint,\n    ['min' =\u003e 1900, 'max' =\u003e 2021],\n);\n```\n\n### Add constraint to Field\n\nAdditional usage of constraint directives is to validate output from your resolve functions.\n\n```php\n$intConstraint; // instance of \\Graphpinator\\ConstraintDirectives\\IntConstraintDirective\n\n\\Graphpinator\\Typesystem\\Field\\Field::create(\n    'year'\n    \\Graphpinator\\Typesystem\\Container::Int(),\n)-\u003eaddDirective(\n    $intConstraint,\n    ['min' =\u003e 1900, 'max' =\u003e 2021],\n);\n```\n\n### Add constraint to Type \u0026 Interface \u0026 InputType\n\nSpecial case is `ObjectConstraint` which declares additional information on which fields must be filled. It is a flexible solution to the input-union problem, but can also be applied on Interface/Type to semantically indicate which values are returned.\n\n```php\nclass DogOrCatInput extends \\Graphpinator\\Typesystem\\InputType\n{\n    protected const NAME = 'DogOrCatInput';\n\n    public funtion __construct(\n        \\Graphpinator\\ConstraintDirectives\\ObjectConstraintDirective $objectConstraint,\n    )\n    {\n        parent::__construct();\n        $this-\u003eaddDirective($objectConstraint, ['exactlyOne' =\u003e ['dog', 'cat']]);\n    }\n\n    protected function getFieldDefinition() : \\Graphpinator\\Typesystem\\Argument\\ArgumentSet\n    {\n        return new \\Graphpinator\\Typesystem\\Argument\\ArgumentSet([\n            \\Graphpinator\\Typesystem\\Argument\\Argument::create('dog', \\Graphpinator\\Typesystem\\Container::String()),\n            \\Graphpinator\\Typesystem\\Argument\\Argument::create('cat', \\Graphpinator\\Typesystem\\Container::String()),\n        ]);\n    }\n}\n```\n\n### Variance\n\nQuestion of variance comes into play because field, argument, and object constraints can be declared in an interface context and then implemented by the concrete type. Traditional rules apply here.\n\n- Covariance for Field constraints - child can restrict parent's constraint, but may not release it.\n- Contravariance for Argument constraints - child can soften parent's constraint, but may not restrict it.\n- Invariance for Object constraints - child must contain the same constraint as parent.\n\n\n### Directive options\n\n- `@stringConstraint`\n    - minLength - `Int`\n    - maxLength - `Int`\n    - regex - `String`\n    - oneOf - `[String!]`\n- `@intConstraint`\n    - min - `Int`\n    - max - `Int`\n    - oneOf - `[Int!]`\n- `@floatConstraint`\n    - min - `Float`\n    - max - `Float`\n    - oneOf - `[Float!]`\n- `@listConstraint`\n    - minItems - `Int`\n    - maxItems - `Int`\n    - unique - `Boolean`\n    - innerList - object with the same arguments to recursivelly apply constraint to inner list\n- `@uploadConstraint`\n    - maxSize - `Int`\n    - mimeType - `[String!]`\n- `@objectConstraint`\n    - atLeastOne - `[String!]`\n    - atMostOne - `[String!]`\n    - exactlyOne - `[String!]`\n    - atLeast - `{count: Int!, from: [String!]!}`\n    - atMost - `{count: Int!, from: [String!]!}`\n    - exactly - `{count: Int!, from: [String!]!}`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraphpql%2Fgraphpinator-constraint-directives","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgraphpql%2Fgraphpinator-constraint-directives","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraphpql%2Fgraphpinator-constraint-directives/lists"}