{"id":15013814,"url":"https://github.com/phillip-kruger/graphql-example","last_synced_at":"2026-03-16T08:30:15.960Z","repository":{"id":44851655,"uuid":"196393340","full_name":"phillip-kruger/graphql-example","owner":"phillip-kruger","description":"A MicroProfile GraphQL Example","archived":true,"fork":false,"pushed_at":"2024-11-29T02:38:07.000Z","size":3002,"stargazers_count":48,"open_issues_count":2,"forks_count":20,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-01-05T22:05:21.770Z","etag":null,"topics":["graphql","microprofile","quarkus","smallrye","wildfly"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phillip-kruger.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-11T12:48:12.000Z","updated_at":"2024-12-14T05:21:54.000Z","dependencies_parsed_at":"2024-09-16T01:00:43.887Z","dependency_job_id":"01f157b1-cc14-4a42-8bb3-e4dc06f96979","html_url":"https://github.com/phillip-kruger/graphql-example","commit_stats":{"total_commits":95,"total_committers":2,"mean_commits":47.5,"dds":"0.052631578947368474","last_synced_commit":"99a7303bced15fe7c4c744ee8b90a231ba9012dc"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phillip-kruger%2Fgraphql-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phillip-kruger%2Fgraphql-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phillip-kruger%2Fgraphql-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phillip-kruger%2Fgraphql-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phillip-kruger","download_url":"https://codeload.github.com/phillip-kruger/graphql-example/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239926553,"owners_count":19719724,"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","microprofile","quarkus","smallrye","wildfly"],"created_at":"2024-09-24T19:44:48.866Z","updated_at":"2026-03-16T08:30:15.901Z","avatar_url":"https://github.com/phillip-kruger.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003e [!WARNING]\n\u003e Rather use https://github.com/phillip-kruger/quarkus-graphql-examples as this is not being maintained and kept us to date.\n\n\n# MicroProfile GraphQL Example\n\nThis is an example of the [MicroProfile GraphQL API](https://github.com/eclipse/microprofile-graphql/) \nusing the [SmallRye Implementation](https://github.com/smallrye/smallrye-graphql). It's done as part of these blog posts:\n\n- [Supersonic Subatomic GraphQL](https://quarkus.io/blog/supersonic-subatomic-graphql/) \n- [Microprofile GraphQL Introduction](https://www.phillip-kruger.com/post/microprofile_graphql_introduction/)\n\nand these [presentation](https://docs.google.com/presentation/d/1FCBw-qcjawBNNOSvqD7eJMUV96TwOL-4QyMkQAFt6tg/edit?usp=sharing)s: \n\n- Upcoming: Global Summit for Java devs'20\n- [Quarkus Insights](https://www.youtube.com/watch?v=nMti8-zIDQs)\n- [#OffTheChain](https://www.youtube.com/watch?v=OOTkQBCtYg0)\n- [joziJUG](https://youtu.be/UqDdDYo-g-8)\n- [SouJava](https://youtu.be/OOnpUeblVPM)\n- [DevConf.cz](https://www.youtube.com/watch?v=lA0L7iB-GV8)\n- [Java cloud conference](http://bit.ly/mp-graphql-presentation)\n\nThe services are exposed with both REST and GraphQL for comparison.\n\n## Person example\n\nThis example expose person data as well as scores that the person got for certain activities.\n\n### Running in Quarkus\n(generate from https://code.quarkus.io/)\n\n```\ncd quarkus-example\nmvn clean install quarkus:dev\n```\n\n### Running in Wildfly\n\n```\ncd wildfly-example\nmvn clean install wildfly:run\n```\n\nThis will start the application on port 8080.\n\n## Testing\n\nGo to http://localhost:8080 to test the application.\n\n- Click on the 'REST' link to open Swagger UI to test the JAX-RS services.\n- Click on the 'GraphQL' link to open GraphiQL UI to test the MicroProfile GraphQL service.\n\nTo stop the application, `ctrl-c` in the maven session.\n\n![screenshot](graphql-example.png)\n\n### Examples\n\nSee the model in the JavaDoc (target/apidocs/index.html)\n\n#### Demo 1 : MicroProfile GraphQL vs JAX-RS \n\n##### REST\n\nSchema: http://localhost:8080/openapi\n\n```\ncurl -X GET \"http://localhost:8080/rest/profile/1\" -H  \"accept: application/json\"\n```\n\n##### GraphQL\n\nSchema: http://localhost:8080/graphql/schema.graphql\n\n```\n{\n  person(id:1){\n    names\n    surname\n  }\n}\n```\n\n#### Demo 2: Stitching\n\n```\n{\n  person(id:1){\n    names\n    surname\n    scores{\n      name\n      value\n    }\n  }\n}\n```\n\nin the log file:\n\n```\n======= Getting person [1] =======\n======= Getting scores [512-46-5065] =======\n```\n\nwithout score\n\n```\n{\n  person(id:1){\n    names\n    surname\n  }\n}\n```\n\nin the log file:\n\n```\n======= Getting person [1] =======\n```\n\n#### Demo 3: Batch\n\n```\n{\n  people{\n    names\n    scores{\n      name\n    }\n  }\n}\n```\nin the log file:\n\n```\n======= Getting scores [797-95-4822, 373-95-3047, 097-87-6795, 347-01-8880, 733-86-4423, 560-99-2165, 091-07-5401, 539-70-2014, 029-18-5986, 287-58-0690] =======\n```\n\n#### Demo 4: More than one request\n\n```\n{\n  person1:person(id:1){\n    surname\n    scores{\n      name\n      value\n    }\n  }\n  person2:person(id:2){\n    surname\n  }\n}\n```\n\nor more than one query:\n\n```\n@Query\npublic Integer getRandomNumber(long seed){\n    Random random = new Random(seed);\n    return random.nextInt();\n}\n```\n\n```\n{\n  person1:person(id:1){\n    surname\n    scores{\n      name\n      value\n    }\n  }\n  randomId:randomNumber(seed:11)\n}\n```\n\n\n#### Demo 5: Collections\n\n```\n{\n  people {\n    surname\n  }\n}\n```\n\n#### Demo 6: JsonB Annotations support\n\n```\n{\n  person(id:1){\n     surname\n     birthDate\n  }\n}\n```\n\n#### Demo 7: DefaultValue\n\n```\n@Query\npublic List\u003cPerson\u003e getPersonsWithSurname(\n        @DefaultValue(\"Doyle\") String surname) {\n    return personService.getPeopleWithSurname(surname);\n}\n```\n\nProviding a parameter\n\n```\n{\n  personsWithSurname(surname:\"Hyatt\") {\n    names\n  }\n}\n```\n\nUing the default\n\n```\n{\n  personsWithSurname {\n    names\n  }\n}\n```\n\n#### Demo 8: Errors and partial responses\n\n##### Validation Errors\n\n```\n{\n  person(id:1){\n     surname\n     scores{\n      thisDoesNotExist\n    }\n  }\n}\n```\n\n##### Partial results\n\n```\n{\n  person(id:1){\n     surname\n     scores{\n      name\n      value\n    }\n  }\n}\n```\n\n#### Demo 9: Metrics and Tracing\n\n##### Servers\n\nThis will be specific to your setup. For me:\n\n**Start Prometheus:**\n```\ncd /opt/Metrics/prometheus-2.19.2.linux-amd64\n./prometheus --config.file=prometheus.yml\n```\n(prometheus.yml is in the root folder)\n\n**Start Grafana:**\n```\nsudo systemctl start grafana-server\n```\n(grafana.json is in the root folder)\n\n**Start Jaeger:**\n```\ndocker run -p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778 -p 16686:16686 -p 14268:14268 jaegertracing/all-in-one:latest\n``` \n\n##### Metrics\n\n```\n@Timed(name = \"personTimer\", description = \"How long does it take to get a Person.\", unit = MetricUnits.NANOSECONDS)\n@Counted(name = \"personCount\", description = \"How many times did we ask for Person.\")\n```\n\n[Grafana Dashboard](http://localhost:3000/d/T2kbtqZGk/person-metrics?orgId=1\u0026refresh=5s)\n\n![metrics](metrics.png)\n\n##### Tracing\n\n[Jaeger Dashboard](http://localhost:16686/search)\n\n![tracing1](tracing1.png)\n![tracing2](tracing2.png)\n\n#### Demo 10: Security\n\n```\n@RolesAllowed(\"admin\")\n```\n\n#### Demo 11: Bean validation\n\n```\n@Query\npublic Integer getRandomNumber(@Min(10) long seed){\n    Random random = new Random(seed);\n    return random.nextInt();\n}\n```\n\n```\n{\n  randomNumber(seed:9)\n}\n```\n\n#### Demo 12: Mutations\n\n```\n    @Mutation\n    public Person updatePerson(Person person){\n        return personService.updateOrCreate(person);\n    }\n    \n    @Mutation\n    public Person deletePerson(Long id){\n        return personService.delete(id);\n    }\n```\n\n##### Create\n```\nmutation CreatePerson{\n  updatePerson(person : \n    {\n      names: \"Phillip\"\n    }\n  ){\n    id\n    names\n    surname\n    profilePictures\n    website\n  }\n}\n```\n\n##### Update \n\n(using the generated id)\n\n```\nmutation UpdatePerson{\n  updatePerson(person : \n    {\n      id: 11, \n      names:\"Phillip\",\n      surname: \"Kruger\", \n      profilePictures: [\n        \"https://pbs.twimg.com/profile_images/1170690050524405762/I8KJ_hF4_400x400.jpg\"\n      ],\n      website: \"http://www.phillip-kruger.com\"\n    }){\n    id\n    names\n    surname\n    profilePictures\n    website\n  }\n}\n```\n\n##### Delete\n\n(using the id)\n\n```\nmutation DeletePerson{\n  deletePerson(id :11){\n    id\n    surname\n  }\n}\n```\n\n#### Demo 13: Context (Experimental)\n\n```\nquarkus.hibernate-orm.log.sql=true\n```\n\n```\n@Inject\nContext context;\n\nJsonArray selectedFields = context.getSelectedFields();\nSystem.out.println(\"selectedFields [\" + selectedFields +\"]\");\n\n```\n\n\n\n```\n{\n  people{\n    surname\n  }\n}\n```\n\n#### Demo 14: Client (Future)\n\nSee the model in the JavaDoc (target/apidocs/index.html)\n\n```\n//@Inject\nPersonGraphQLClient graphQLClient = GraphQlClientBuilder.newBuilder().build(PersonGraphQLClient.class);\n```\n\n```\nPerson graphQLPerson = graphQLClient.getPerson(id);\n        \nSystem.err.println(\"================ GRAPHQL ================\");\nSystem.err.println(graphQLPerson);\n```\n#### Apendix: Introspection\n\n```\n{\n  __schema{\n    types {\n      name\n      kind\n    }\n  }\n}\n \n```\n\n#### The Introspection query used by GrapiQL\n\n```\nquery IntrospectionQuery {\n  __schema {\n    queryType { name }\n    mutationType { name }\n    subscriptionType { name }\n    types {\n      ...FullType\n    }\n    directives {\n      name\n      description\n      locations\n      args {\n        ...InputValue\n      }\n    }\n  }\n}\n\nfragment FullType on __Type {\n  kind\n  name\n  description\n  fields(includeDeprecated: true) {\n    name\n    description\n    args {\n      ...InputValue\n    }\n    type {\n      ...TypeRef\n    }\n    isDeprecated\n    deprecationReason\n  }\n  inputFields {\n    ...InputValue\n  }\n  interfaces {\n    ...TypeRef\n  }\n  enumValues(includeDeprecated: true) {\n    name\n    description\n    isDeprecated\n    deprecationReason\n  }\n  possibleTypes {\n    ...TypeRef\n  }\n}\n\nfragment InputValue on __InputValue {\n  name\n  description\n  type { ...TypeRef }\n  defaultValue\n}\n\nfragment TypeRef on __Type {\n  kind\n  name\n  ofType {\n    kind\n    name\n    ofType {\n      kind\n      name\n      ofType {\n        kind\n        name\n        ofType {\n          kind\n          name\n          ofType {\n            kind\n            name\n            ofType {\n              kind\n              name\n              ofType {\n                kind\n                name\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n### Schemas\n\n- REST: http://localhost:8080/openapi\n- GraphQL: http://localhost:8080/graphql/schema.graphql\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphillip-kruger%2Fgraphql-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphillip-kruger%2Fgraphql-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphillip-kruger%2Fgraphql-example/lists"}