{"id":15043132,"url":"https://github.com/vladislavsevruk/graphqlrequestbodygenerator","last_synced_at":"2025-04-14T21:12:50.049Z","repository":{"id":44657707,"uuid":"260005750","full_name":"VladislavSevruk/GraphQlRequestBodyGenerator","owner":"VladislavSevruk","description":"This utility library helps to generate body for GraphQL request using POJO and annotations.","archived":false,"fork":false,"pushed_at":"2022-11-11T13:43:54.000Z","size":417,"stargazers_count":14,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-04-14T21:12:45.036Z","etag":null,"topics":["annotations","generator","graphql","graphql-annotations","graphql-client","graphql-java","java","request-body"],"latest_commit_sha":null,"homepage":"","language":"Java","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/VladislavSevruk.png","metadata":{"files":{"readme":"ReadMe.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-04-29T18:13:40.000Z","updated_at":"2024-07-21T20:16:19.000Z","dependencies_parsed_at":"2022-09-02T07:11:46.544Z","dependency_job_id":null,"html_url":"https://github.com/VladislavSevruk/GraphQlRequestBodyGenerator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VladislavSevruk%2FGraphQlRequestBodyGenerator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VladislavSevruk%2FGraphQlRequestBodyGenerator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VladislavSevruk%2FGraphQlRequestBodyGenerator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VladislavSevruk%2FGraphQlRequestBodyGenerator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/VladislavSevruk","download_url":"https://codeload.github.com/VladislavSevruk/GraphQlRequestBodyGenerator/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248961237,"owners_count":21189993,"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":["annotations","generator","graphql","graphql-annotations","graphql-client","graphql-java","java","request-body"],"created_at":"2024-09-24T20:48:36.870Z","updated_at":"2025-04-14T21:12:50.021Z","avatar_url":"https://github.com/VladislavSevruk.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/VladislavSevruk/GraphQlRequestBodyGenerator.svg?branch=develop)](https://travis-ci.com/VladislavSevruk/GraphQlRequestBodyGenerator)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=VladislavSevruk_GraphQlRequestBodyGenerator\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=VladislavSevruk_GraphQlRequestBodyGenerator)\n[![Code Coverage](https://sonarcloud.io/api/project_badges/measure?project=VladislavSevruk_GraphQlRequestBodyGenerator\u0026metric=coverage)](https://sonarcloud.io/component_measures?id=VladislavSevruk_GraphQlRequestBodyGenerator\u0026metric=coverage)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.vladislavsevruk/graphql-request-body-generator/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.vladislavsevruk/graphql-request-body-generator)\n[![Gradle Plugin Portal](https://img.shields.io/maven-metadata/v/https/plugins.gradle.org/m2/io/github/vladislavsevruk/graphql-model-generator-plugin/io.github.vladislavsevruk.graphql-model-generator-plugin.gradle.plugin/maven-metadata.xml.svg?colorB=4ac41c\u0026label=gradle%20plugin)](https://plugins.gradle.org/plugin/io.github.vladislavsevruk.graphql-model-generator-plugin)\n\n# GraphQL Request Body Generator\nThis utility library helps to generate request body for [GraphQL](http://spec.graphql.org/June2018/) queries using POJOs.\n\n## Table of contents\n* [Getting started](#getting-started)\n  * [Maven](#maven)\n  * [Gradle](#gradle)\n* [Usage](#usage)\n  * [Field marking strategy](#field-marking-strategy)\n  * [Prepare POJO model](#prepare-pojo-model)\n    * [Automatic generation](#automatic-generation)\n      * [Gradle plugin](#gradle-plugin)\n    * [Manual generation](#manual-generation)\n      * [Selection set](#selection-set)\n        * [GqlField](#gqlfield)\n        * [GqlDelegate](#gqldelegate)\n        * [GqlUnion](#gqlunion)\n        * [GqlIgnore](#gqlignore)\n      * [Input object value](#input-object-value)\n        * [GqlField](#gqlfield-1)\n        * [GqlInput](#gqlinput)\n        * [GqlDelegate](#gqldelegate-1)\n        * [GqlIgnore](#gqlignore-1)\n  * [Generate request body](#generate-request-body)\n    * [Operation selection set](#operation-selection-set)\n    * [Loop breaking strategy](#loop-breaking-strategy)\n    * [Arguments](#arguments)\n      * [Input argument](#input-argument)\n      * [Variables](#variables)\n      * [Delegate argument](#delegate-argument)\n      * [Mutation argument strategy](#mutation-argument-strategy)\n    * [Operation Alias](#operation-alias)\n* [License](#license)\n\n## Getting started\nTo add library to your project perform next steps:\n\n### Maven\nAdd the following dependency to your ``pom.xml``:\n```xml\n\u003cdependency\u003e\n      \u003cgroupId\u003ecom.github.vladislavsevruk\u003c/groupId\u003e\n      \u003cartifactId\u003egraphql-request-body-generator\u003c/artifactId\u003e\n      \u003cversion\u003e1.0.16\u003c/version\u003e\n\u003c/dependency\u003e\n```\n### Gradle\nAdd the following dependency to your ``build.gradle``:\n```groovy\nimplementation 'com.github.vladislavsevruk:graphql-request-body-generator:1.0.16'\n```\n\n## Usage\nFirst of all we need to choose field marking strategy that will be used for GraphQL operation generation.\n\n### Field marking strategy\nThere are two predefined field marking strategy that define the way how builder determine if field should be used for\nGraphQL operation generation:\n* Use all fields except ones with [GqlIgnore](graphql-request-body-generator-annotation/src/main/java/com/github/vladislavsevruk/generator/annotation/GqlIgnore.java)\n  annotation \\[default]\n* Use only fields with one of [GqlField](graphql-request-body-generator-annotation/src/main/java/com/github/vladislavsevruk/generator/annotation/GqlField.java)\n  or [GqlDelegate](graphql-request-body-generator-annotation/src/main/java/com/github/vladislavsevruk/generator/annotation/GqlDelegate.java) annotations\n\nCurrent strategy for both [operation selection set](http://spec.graphql.org/June2018/#sec-Selection-Sets) and mutation\n[input object values](http://spec.graphql.org/June2018/#sec-Input-Object-Values) can be set using\n[FieldMarkingStrategySourceManager](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/strategy/marker/FieldMarkingStrategySourceManager.java):\n```kotlin\nFieldMarkingStrategySourceManager.selectionSet().useAllExceptIgnoredFieldsStrategy();\n// or\nFieldMarkingStrategySourceManager.input().useOnlyMarkedFieldsStrategy();\n```\n\nHowever, you can set your own custom [FieldMarkingStrategy](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/strategy/marker/FieldMarkingStrategy.java):\n```kotlin\nFieldMarkingStrategySourceManager.selectionSet().useCustomStrategy(field -\u003e true);\n```\n\n### Prepare POJO model\nThen we need to prepare POJO models that will be used for GraphQL operation generation according to chosen field marking\nstrategy.\n\n### Automatic generation\nFor automatic generation of POJO models at your project you can use following options:\n\n### Gradle plugin\nAdd the following plugin to your ``build.gradle``:\n```groovy\nplugins {\n  id 'io.github.vladislavsevruk.graphql-model-generator-plugin' version '1.0.0'\n}\n```\nThis plugin will add additional ``generateGraphqlModels`` task before ``javaCompile`` that will automatically generate\nPOJO models based on GraphQL schema file. Generation results can be customized using followed options of\n``graphqlModelGenerator`` extension:\n\n```groovy\nimport com.github.vladislavsevruk.generator.model.graphql.constant.*\n\ngraphqlModelGenerator {\n  addJacksonAnnotations = false\n  entitiesPrefix = ''\n  entitiesPostfix = ''\n  pathToSchemaFile = '/path/to/schema.graphqls'\n  targetPackage = 'com.myorg'\n  treatArrayAs = ElementSequence.LIST\n  treatFloatAs = GqlFloatType.DOUBLE\n  treatIdAs = GqlIntType.STRING\n  treatIntAs = GqlIntType.INTEGER\n  updateNamesToJavaStyle = true\n  useLombokAnnotations = false\n  usePrimitivesInsteadOfWrappers = false\n  useStringsInsteadOfEnums = false\n}\n```\n\n* __addJacksonAnnotations__ reflects if jackson annotations should be added to fields for proper mapping using Jackson \nlibrary. Default value is ``false``;\n* __entitiesPrefix__ is used for adding specific prefix to generated POJO model names. Default value is empty string;\n* __entitiesPostfix__ is used for adding specific postfix to generated POJO model names. Default value is empty string;\n* __pathToSchemaFile__ is used for setting location of GraphQL schema file. Default location is \n``src/main/resources/graphql/schema.graphqls``;\n* __targetPackage__ is used for setting specific package name for generated POJO models. Default value is\n``com.github.vladislavsevruk.model``;\n* __treatArrayAs__ is used for setting entity that should be used for GraphQL array type generation. Can be one of \n* following values: ``ARRAY``, ``COLLECTION``, ``ITERABLE``, ``LIST``, ``SET``. Default value is ``LIST``;\n* __treatFloatAs__ is used for setting entity that should be used for GraphQL array type generation. Can be one of\n* following values: ``BIG_DECIMAL``, ``DOUBLE``, ``FLOAT``, ``STRING``. Default value is ``DOUBLE``;\n* __treatIdAs__ is used for setting entity that should be used for GraphQL array type generation. Can be one of\n* following values: ``BIG_INTEGER``, ``INTEGER``, ``LONG``, ``STRING``. Default value is ``STRING``;\n* __treatIntAs__ is used for setting entity that should be used for GraphQL array type generation. Can be one of\n* following values: ``BIG_INTEGER``, ``INTEGER``, ``LONG``, ``STRING``. Default value is ``INTEGER``;\n* __updateNamesToJavaStyle__ reflects if entities and fields from GraphQL schema should be updated to follow default \njava convention (upper camel case for classes and lower camel case for fields). Default value is ``true``;\n* __useLombokAnnotations__ reflects if lombok annotations should be used for POJO methods generation instead of \nones generated by this plugin. Default value is ``false``;\n* __usePrimitivesInsteadOfWrappers__ reflects if java primitives should be used for GraphQL scalar types instead of \njava primitive wrapper classes. Default value is ``false``;\n* __useStringsInsteadOfEnums__ reflects if GraphQL enum fields at type entities should be converted to string type.\nDefault value is ``false``;\n\n### Manual generation\nHowever, you still can create and customize model by yourself following rules described below.\n\n### Selection set\nSelection set generation is based only on fields that are declared at class or it superclasses and doesn't involve\ndeclared methods.\n\n#### GqlField\n[GqlField](graphql-request-body-generator-annotation/src/main/java/com/github/vladislavsevruk/generator/annotation/GqlField.java) annotation marks model fields\nthat should be treated as [GraphQL field](http://spec.graphql.org/June2018/#sec-Language.Fields):\n```java\npublic class User {\n    @GqlField\n    private Long id;\n}\n```\n\nBy default field name will be used for generation but you can override it using __name__ method:\n```java\npublic class User {\n    @GqlField(name = \"wishListItemsUrls\")\n    private List\u003cString\u003e wishListItems;\n}\n```\n\nSome fields may contain a [selection set](http://spec.graphql.org/June2018/#sec-Selection-Sets) so if you mark field\nusing __withSelectionSet__ method it will be treated as field that have nested fields:\n```java\npublic class User {\n    @GqlField(withSelectionSet = true)\n    private Contacts contacts;\n    @GqlField(withSelectionSet = true)\n    private List\u003cOrder\u003e orders;\n}\n\npublic class Contacts {\n    @GqlField\n    private String email;\n    @GqlField\n    private String phoneNumber;\n}\n\npublic class Order {\n    @GqlField\n    private Long id;\n    @GqlField\n    private Boolean isDelivered;\n}\n```\n\nAnnotation also has method __nonNull__ that allow to mark field that was denoted as\n[non-null](http://spec.graphql.org/June2018/#sec-Type-System.Non-Null) at GraphQL schema:\n```java\npublic class User {\n    @GqlField(nonNull = true)\n    private Long id;\n}\n```\n\nIf field requires [arguments](http://spec.graphql.org/June2018/#sec-Language.Arguments) for GraphQL operation they can\nbe provided via __arguments__ function:\n```java\npublic class User {\n    @GqlField(arguments = { @GqlFieldArgument(name = \"width\", value = \"100\"),\n                            @GqlFieldArgument(name = \"height\", value = \"50\") })\n    private String profilePic;\n}\n```\n\nValues of [GqlFieldArgument](graphql-request-body-generator-annotation/src/main/java/com/github/vladislavsevruk/generator/annotation/GqlFieldArgument.java)\nannotation will be added to selection set \"as is\" so you may need to escape quotes for literal values:\n```java\npublic class User {\n    @GqlField(withSelectionSet = true,\n              arguments = @GqlFieldArgument(name = \"sortBy\", value = \"\\\"orderDate DESC\\\"\"))\n    private List\u003cOrder\u003e orders;\n}\n\npublic class Order {\n    @GqlField\n    private Long id;\n    @GqlField\n    private Date orderDate;\n}\n```\n\nAlso [alias](http://spec.graphql.org/June2018/#sec-Field-Alias) can be specified for field using self-titled method:\n```java\npublic class User {\n    @GqlField(name = \"profilePic\",\n              alias = \"smallPic\",\n              arguments = { @GqlFieldArgument(name = \"size\", value = \"64\")})\n    private String smallPic;\n    @GqlField(name = \"profilePic\",\n              alias = \"bigPic\",\n              arguments = { @GqlFieldArgument(name = \"size\", value = \"1024\")})\n    private String bigPic;\n}\n```\n\n#### GqlDelegate\n[GqlDelegate](graphql-request-body-generator-annotation/src/main/java/com/github/vladislavsevruk/generator/annotation/GqlDelegate.java) is used for complex fields\nto treat its inner fields like they are declared at same class where field itself declared:\n```java\npublic class User {\n    @GqlDelegate\n    private UserInfo userInfo;\n} \n\npublic class UserInfo {\n    @GqlField\n    private String firstName;\n    @GqlField\n    private String lastName;\n}\n```\n\nCode above is equivalent to:\n```java\npublic class User {\n    @GqlField\n    private String firstName;\n    @GqlField\n    private String lastName;\n}\n```\n\n#### GqlUnion\n[GqlUnion](graphql-request-body-generator-annotation/src/main/java/com/github/vladislavsevruk/generator/annotation/GqlUnion.java) annotation is used for fields\nthat should be treated as [union](http://spec.graphql.org/June2018/#sec-Unions):\n```java\npublic class Order {\n    @GqlField\n    private Long id;\n    @GqlField\n    private Date orderDate;\n    @GqlUnion({ @GqlUnionType(Book.class), @GqlUnionType(value = BoardGame.class, name = \"Game\") })\n    private OrderItem orderItem;\n}\n\npublic class OrderItem {\n    @GqlField\n    private Long id;\n    @GqlField\n    private String title;\n}\n\npublic class Book extends OrderItem {\n    @GqlField\n    private Long numberOfPages;\n}\n\npublic class BoardGame extends OrderItem {\n    @GqlField\n    private Long numberOfPlayers;\n}\n```\n\n#### GqlIgnore\n[GqlIgnore](graphql-request-body-generator-annotation/src/main/java/com/github/vladislavsevruk/generator/annotation/GqlIgnore.java) is used with \"all fields\nexcept ignored\" [field marking strategy](#field-marking-strategy) for marking field that shouldn't be used for\ngeneration:\n```java\npublic class UserInfo {\n    private String firstName;\n    @GqlIgnore\n    private String fullName;\n    private String lastName;\n}\n```\n\n### Input object value\nInput object value generation goes through fields that are declared at class or it superclasses and gets values from\nrelated getter methods (or field itself if no related getter found).\n\n#### GqlField\n[GqlField](graphql-request-body-generator-annotation/src/main/java/com/github/vladislavsevruk/generator/annotation/GqlField.java) annotation is also used for\n[input object value](http://spec.graphql.org/June2018/#sec-Input-Object-Values) generation and marks\n[input values](http://spec.graphql.org/June2018/#sec-Input-Values) of any type:\n```java\npublic class User {\n    @GqlField\n    private Long id;\n    @GqlField\n    private Contacts contacts;\n}\n\npublic class Contacts {\n    @GqlField\n    private String email;\n    @GqlField\n    private String phoneNumber;\n}\n```\n\nBy default field name will be used for generation but you can override it using __name__ method:\n```java\npublic class User {\n    @GqlField(name = \"wishListItemsUrls\")\n    private List\u003cString\u003e wishListItems;\n}\n```\n\n#### GqlInput\n[GqlInput](graphql-request-body-generator-annotation/src/main/java/com/github/vladislavsevruk/generator/annotation/GqlInput.java) annotation is used with methods\nand helps to point to related GraphQL field if method name doesn't match field getter pattern:\n```java\npublic class User {\n    @GqlField\n    private String name;\n    @GqlField\n    private String surname;\n\n    @GqlInput(name = \"name\")\n    public String getFirstName() {\n        return name;\n    }\n\n    @GqlInput(name = \"surname\")\n    public String getLastName() {\n        return surname;\n    }\n}\n```\n\nIf provided name doesn't match any of GraphQL fields at model result of method execution will be treated as new field:\n```java\npublic class User {\n    @GqlField\n    private String firstName;\n    @GqlField\n    private String lastName;\n\n    @GqlInput(name = \"fullName\")\n    public String getFullName() {\n        return firstName + \" \" + lastName;\n    }\n}\n```\n\n#### GqlDelegate\n[GqlDelegate](graphql-request-body-generator-annotation/src/main/java/com/github/vladislavsevruk/generator/annotation/GqlDelegate.java) is used for complex values\nto treat its inner fields like they are declared at same class where field itself declared:\n```java\npublic class User {\n    @GqlDelegate\n    private UserInfo userInfo;\n} \n\npublic class UserInfo {\n    @GqlField\n    private String firstName;\n    @GqlField\n    private String lastName;\n}\n```\n\nModels above are equivalent to:\n```java\npublic class User {\n    @GqlField\n    private String firstName;\n    @GqlField\n    private String lastName;\n}\n```\n\nLike [GqlInput](#gqlinput) __GqlDelegate__ can be applied to methods without related GraphQL field. In this case return\nvalue of method will be treated as delegated field:\n```java\npublic class User {\n    @GqlDelegate\n    public UserInfo getUserInfo() {\n        // UserInfo generation\n    }\n} \n\npublic class UserInfo {\n    @GqlField\n    private String firstName;\n    @GqlField\n    private String lastName;\n}\n```\n\nCode above is equivalent to:\n```java\npublic class User {\n    @GqlField\n    private String firstName;\n    @GqlField\n    private String lastName;\n}\n```\n\n\n#### GqlIgnore\n[GqlIgnore](graphql-request-body-generator-annotation/src/main/java/com/github/vladislavsevruk/generator/annotation/GqlIgnore.java) is used with \"all fields\nexcept ignored\" [field marking strategy](#field-marking-strategy) for marking field that shouldn't be used for\ngeneration:\n```java\npublic class UserInfo {\n    private String firstName;\n    @GqlIgnore\n    private String fullName;\n    private String lastName;\n}\n```\n\n### Generate request body\nOnce POJO models are ready we can generate GraphQL operation using\n[GqlRequestBodyGenerator](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/GqlRequestBodyGenerator.java):\n```kotlin\n// query\nString query = GqlRequestBodyGenerator.query(\"allUsers\").selectionSet(User.class).generate();\n\n// prepare input model\nUser newUser = new User();\nnewUser.setFirstName(\"John\");\nnewUser.setLastName(\"Doe\");\n// mutation\nGqlInputArgument input = GqlInputArgument.of(newUser);\nString mutation = GqlRequestBodyGenerator.mutation(\"newUser\").arguments(input).selectionSet(User.class)\n        .generate();\n```\n\nGenerated operation is wrapped into json and can be passed as body to any API Client. If you want to generate pure \nunwrapped to JSON GraphQL query you can use ``GqlRequestBodyGenerator.unwrapped()`` first, all other methods calls \nremain the same:\n```kotlin\n// query\nString query = GqlRequestBodyGenerator.unwrapped().query(\"allUsers\").selectionSet(User.class)\n        .generate();\n\n// prepare input model\nUser newUser = new User();\nnewUser.setFirstName(\"John\");\nnewUser.setLastName(\"Doe\");\n// mutation\nGqlInputArgument input = GqlInputArgument.of(newUser);\nString mutation = GqlRequestBodyGenerator.unwrapped().mutation(\"newUser\").arguments(input)\n        .selectionSet(User.class).generate();\n```\n\n#### Operation selection set\nBy default, all marked fields will be used for selection set generation. However, you can generate selection set using\none of [predefined fields picking strategies](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/strategy/picker/selection/SelectionSetGenerationStrategy.java):\n- pick all marked fields \\[default]\n```kotlin\nString query = GqlRequestBodyGenerator.query(\"allUsers\")\n        .selectionSet(User.class, SelectionSetGenerationStrategy.allFields()).generate();\n// same result as\nString query2 = GqlRequestBodyGenerator.query(\"allUsers\").selectionSet(User.class).generate();\n```\n\n- pick only fields with __id__ name or fields that have nested field with __id__ name\n```kotlin\nString query = GqlRequestBodyGenerator.query(\"allUsers\")\n        .selectionSet(User.class, SelectionSetGenerationStrategy.onlyId()).generate();\n```\n\n- pick only fields that are marked as [non-null](http://spec.graphql.org/June2018/#sec-Type-System.Non-Null)\n```kotlin\nString query = GqlRequestBodyGenerator.query(\"allUsers\")\n        .selectionSet(User.class, SelectionSetGenerationStrategy.onlyNonNull()).generate();\n```\n\n- pick all except fields with [selection set](http://spec.graphql.org/June2018/#sec-Selection-Sets)\n```kotlin\nString query = GqlRequestBodyGenerator.query(\"allUsers\")\n        .selectionSet(User.class, SelectionSetGenerationStrategy.fieldsWithoutSelectionSets()).generate();\n```\n\nAlso you can provide your own custom fields picking strategy that implements\n[FieldsPickingStrategy](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/strategy/picker/selection/FieldsPickingStrategy.java)\nfunctional interface:\n```kotlin\nString query = GqlRequestBodyGenerator.query(\"allUsers\")\n        .selectionSet(User.class, field -\u003e field.getName().contains(\"Name\")).generate();\n```\n\nIf you want to use generic models it's recommended to provide them via\n[TypeProvider](https://github.com/VladislavSevruk/TypeResolver/blob/develop/src/main/java/com/github/vladislavsevruk/resolver/type/TypeProvider.java):\n```kotlin\nString query = GqlRequestBodyGenerator.query(\"allUsers\")\n        .selectionSet(new TypeProvider\u003cUser\u003cUserInfo\u003e\u003e() {}).generate();\n```\n\n#### Loop breaking strategy\nSome models may contain circular type reference on each other, like\n```java\npublic class Parent {\n  @GqlField\n  private Long id;\n  @GqlField(withSelectionSet = true)\n  private List\u003cChild\u003e children;\n}\n\npublic class Child {\n  @GqlField\n  private Long id;\n  @GqlField(withSelectionSet = true)\n  private Parent parent;\n}\n```\nwhich leads to stack overflow during selection set generation. To avoid this library uses loop breaking mechanism that\ncan be customized using one of \n[predefined loop breaking strategies](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/strategy/looping/LoopBreakingStrategy.java):\n- do not include detected looped item to selection set \\[default]\n```kotlin\nString query = GqlRequestBodyGenerator.query(\"queryName\").selectionSet(Parent.class)\n        .generate();\n```\nwill result to\n```json\n{\"query\":\"{queryName{id children{id}}}\"}\n```\n- allow received nesting level\n```kotlin\nint nestingLevel = 1;\nString query = GqlRequestBodyGenerator.query(\"queryName\")\n        .selectionSet(Parent.class, EndlessLoopBreakingStrategy.nestingStrategy(nestingLevel))\n        .generate();\n```\nwill result to\n```json\n{\"query\":\"{queryName{id children{id parent{id children{id}}}}}\"}\n```\n\nThis strategy will be used as default during generation but you can set another max nesting level for specific field\nusing ``maxNestingLoopLevel`` method at [GqlField](#gqlfield) and [GqlUnionType](#gqlunion) annotations.\n```java\npublic class Parent {\n  @GqlField\n  private Long id;\n  @GqlField(withSelectionSet = true, maxNestingLoopLevel = 1)\n  private List\u003cChild\u003e children;\n}\n\npublic class Child {\n  @GqlField\n  private Long id;\n  @GqlField(withSelectionSet = true)\n  private Parent parent;\n}\n```\n\nAlso you can provide your own custom loop breaking strategy that implements\n[LoopBreakingStrategy](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/strategy/looping/LoopBreakingStrategy.java)\nfunctional interface:\n```kotlin\nString query = GqlRequestBodyGenerator.query(\"queryName\")\n        .selectionSet(Parent.class,\n                (typeMeta, trace) -\u003e typeMeta.getType().equals(Parent.class))\n        .generate();\n```\n\n#### Arguments\nSome operations may require [arguments](http://spec.graphql.org/June2018/#sec-Language.Arguments) (to pick specific item\nor filter items list, for example) so you can provide necessary arguments to operation using\n[GqlArgument](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/param/GqlArgument.java) class:\n```kotlin\nGqlArgument\u003cLong\u003e idArgument = GqlArgument.of(\"id\", 1L);\nString query = GqlRequestBodyGenerator.query(\"user\").arguments(idArgument)\n        .selectionSet(User.class).generate();\n```\n\nIf you need to provide several arguments you can use varargs:\n```kotlin\nGqlArgument\u003cList\u003cString\u003e\u003e firstNameArgument = GqlArgument.of(\"lastName\", Arrays.asList(\"John\", \"Jane\"));\nGqlArgument\u003cString\u003e lastNameArgument = GqlArgument.of(\"lastName\", \"Doe\");\nString query = GqlRequestBodyGenerator.query(\"activeUsers\").arguments(firstNameArgument, lastNameArgument)\n        .selectionSet(User.class).generate();\n```\n\nor iterables:\n```kotlin\nGqlArgument\u003cList\u003cString\u003e\u003e firstNameArgument = GqlArgument.of(\"lastName\", Arrays.asList(\"John\", \"Jane\"));\nGqlArgument\u003cString\u003e lastNameArgument = GqlArgument.of(\"lastName\", \"Doe\");\nList\u003cGqlArgument\u003c?\u003e\u003e arguments = Arrays.asList(firstNameArgument, lastNameArgument);\nString query = GqlRequestBodyGenerator.query(\"activeUsers\").arguments(arguments)\n        .selectionSet(User.class).generate();\n```\n\n#### Input argument\nMutations usually use __input__ argument to pass complex [input objects](http://spec.graphql.org/June2018/#sec-Input-Objects).\nYou can use [GqlInputArgument](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/param/GqlInputArgument.java) to pass\n__input object__ for mutation:\n```kotlin\n// prepare input model\nUser newUser = new User();\nnewUser.setFirstName(\"John\");\nnewUser.setLastName(\"Doe\");\n// mutation\nGqlInputArgument\u003cUser\u003e inputArgument = GqlInputArgument.of(newUser);\n// the same as GqlArgument\u003cUser\u003e inputArgument = GqlArgument.of(\"input\", newUser);\nString mutation = GqlRequestBodyGenerator.mutation(\"newUser\").arguments(inputArgument)\n        .selectionSet(User.class).generate();\n```\n\nBy default, __input object__ will be generated using non-null field values but like [selection set](#operation-selection-set)\n__input object__ can be generated using\n[predefined fields picking strategies](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/strategy/picker/mutation/InputGenerationStrategy.java):\n- pick all marked fields\n```kotlin\nString query = GqlRequestBodyGenerator.mutation(\"newUser\")\n        .arguments(InputGenerationStrategy.allFields(), inputArgument).selectionSet(User.class).generate();\n```\n\n- pick only fields with non-null value\n```kotlin\nString query = GqlRequestBodyGenerator.mutation(\"newUser\")\n        .arguments(InputGenerationStrategy.nonNullsFields(), inputArgument).selectionSet(User.class).generate();\n```\n\nBut you can provide your own input fields picking strategy that implements\n[InputFieldsPickingStrategy](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/strategy/picker/mutation/InputFieldsPickingStrategy.java)\ninterface:\n```kotlin\nInputFieldsPickingStrategy inputFieldsPickingStrategy = field -\u003e field.getName().contains(\"Name\");\nString query = GqlRequestBodyGenerator.mutation(\"newUser\")\n        .arguments(inputFieldsPickingStrategy, inputArgument).selectionSet(User.class).generate();\n```\n\n#### Variables\nAs GraphQL query can be parameterized with [variables](https://spec.graphql.org/June2018/#sec-Language.Variables) you\ncan generate GraphQL operation body that way passing values as operation arguments and using one of\n[predefined variables generation strategies](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/strategy/variable/VariableGenerationStrategy.java):\n- generate only for arguments of [GqlVariableArgument](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/param/GqlVariableArgument.java)\n  type:\n```kotlin\nString variableName = \"id\";\nGqlParameterValue\u003cInteger\u003e variable = GqlVariableArgument.of(variableName, variableName, 1, true);\nString query = GqlRequestBodyGenerator.query(\"getProfile\")\n        .arguments(VariableGenerationStrategy.byArgumentType(), variable)\n        .selectionSet(User.class).generate();\n```\n\n- generate only for arguments with value type annotated by\n  [GqlVariableType](graphql-request-body-generator-annotation/src/main/java/com/github/vladislavsevruk/generator/annotation/GqlVariableType.java) type;\n```java\n@GqlVariableType(variableType = \"ContactsData\", variableName = \"contactsData\")\npublic class Contacts {\n  @GqlField\n  private String email;\n  @GqlField\n  private String phoneNumber;\n\n  // getters and setters\n    ...\n}\n```\n```kotlin\nContacts contacts = new Contacts().setEmail(\"test@domain.com\").setPhoneNumber(\"3751945\");\nString variableName = \"id\";\nGqlArgument\u003cContacts\u003e variable = GqlArgument.of(\"contacts\", contacts);\nString query = GqlRequestBodyGenerator.mutation(\"updateContacts\")\n        .arguments(VariableGenerationStrategy.annotatedArgumentValueType(), variable)\n        .selectionSet(Contacts.class).generate();\n```\n\nOr you can provide your own variables generation strategy that implements\n[VariablePickingStrategy](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/strategy/variable/VariablePickingStrategy.java)\ninterface.\n\n#### Delegate argument\nIf query or mutation has big arguments number it may be easier to create object to keep them all at one place and manage\ntogether. In that case you can use [GqlDelegateArgument](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/param/GqlDelegateArgument.java)\nto simply pass such object as argument:\n```kotlin\nContacts contacts = new Contacts().setEmail(\"test@domain.com\").setPhoneNumber(\"3751945\");\nGqlArgument\u003cContacts\u003e delegateArgument = GqlDelegateArgument.of(contacts);\nString query = GqlRequestBodyGenerator.mutation(\"updateContacts\")\n        .arguments(delegateArgument).selectionSet(Contacts.class).generate();\n```\n\nIf you want to generate variables for delegated values you need to pass flag to\n[GqlDelegateArgument](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/param/GqlDelegateArgument.java)\nand add [GqlVariableType](graphql-request-body-generator-annotation/src/main/java/com/github/vladislavsevruk/generator/annotation/GqlVariableType.java)\nannotations to fields that should be passed as variables:\n\n```java\npublic class Contacts {\n  @GqlField\n  @GqlVariableType\n  private String email;\n  @GqlField\n  @GqlVariableType\n  private String phoneNumber;\n\n  // getters and setters\n    ...\n}\n```\n```kotlin\nContacts contacts = new Contacts().setEmail(\"test@domain.com\").setPhoneNumber(\"3751945\");\nGqlArgument\u003cContacts\u003e delegateArgument = GqlDelegateArgument.of(contacts, true);\nString query = GqlRequestBodyGenerator.mutation(\"updateContacts\")\n        .arguments(delegateArgument).selectionSet(Contacts.class).generate();\n```\n\n#### Mutation argument strategy\nBy default, only __input__ argument value is treated as [complex input objects](http://spec.graphql.org/June2018/#sec-Input-Objects)\naccording to GraphQL specification. However, you can use other\n[model arguments strategies](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/strategy/argument/ModelArgumentGenerationStrategy.java)\nto override this behavior:\n- treat only __input__ argument as potential complex input object\n```kotlin\nString query = GqlRequestBodyGenerator.mutation(\"newUser\")\n        .arguments(ModelArgumentGenerationStrategy.onlyInputArgument(), inputArgument)\n        .selectionSet(User.class).generate();\n```\n\n- treat any argument as potential complex input object\n```kotlin\nString query = GqlRequestBodyGenerator.mutation(\"newUser\")\n        .arguments(ModelArgumentGenerationStrategy.anyArgument(), inputArgument)\n        .selectionSet(User.class).generate();\n```\n\nYou can also provide your own mutation arguments strategy that implements\n[ModelArgumentStrategy](graphql-request-body-generator/src/main/java/com/github/vladislavsevruk/generator/strategy/argument/ModelArgumentStrategy.java)\ninterface:\n```kotlin\nModelArgumentStrategy modelArgumentStrategy = argument -\u003e argument.getName().contains(\"Model\");\nString query = GqlRequestBodyGenerator.mutation(\"newUser\")\n        .arguments(modelArgumentStrategy, inputArgument).selectionSet(User.class).generate();\n```\n\n### Operation Alias\nWhen generating operation with [variables](#variables) resulted new operation will be anonymous by default. You can set\noperation alias for convenience using ``operationAlias`` method:\n```kotlin\nString variableName = \"id\";\nString operationAlias = \"id\";\nGqlParameterValue\u003cInteger\u003e variable = GqlVariableArgument.of(variableName, variableName, 1, true);\nString query = GqlRequestBodyGenerator.query(\"getProfile\")\n        .operationAlias(\"getProfileParameterized\")\n        .arguments(VariableGenerationStrategy.byArgumentType(), variable)\n        .selectionSet(User.class).generate();\n```\n\n## License\nThis project is licensed under the MIT License, you can read the full text [here](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvladislavsevruk%2Fgraphqlrequestbodygenerator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvladislavsevruk%2Fgraphqlrequestbodygenerator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvladislavsevruk%2Fgraphqlrequestbodygenerator/lists"}