├── .github ├── dependabot.yml └── workflows │ ├── dgs-client.yml │ ├── dgs-codegen.yml │ ├── dgs-fileupload.yml │ ├── dgs-kotlin-co.yml │ ├── dgs-kotlin.yml │ ├── dgs-subscription-sse.yml │ ├── dgs-subscription-ui.yml │ ├── dgs-subscription-ws.yml │ ├── dgs-webflux.yml │ ├── dgs.yml │ ├── graphql-kotlin.yml │ ├── legacy-graphql-java-kickstart-annotations.yml │ ├── legacy-graphql-java-kickstart-webclient.yml │ ├── legacy-graphql-java-kickstart.yml │ ├── legacy-graphql-java.yml │ ├── legacy-graphql-spqr.yml │ ├── spring-graphql-querydsl.yml │ ├── spring-graphql-rsocket-kotlin-co.yml │ ├── spring-graphql-webflux.yml │ ├── spring-graphql-webmvc.yml │ └── spring-graphql.yml ├── .gitignore ├── LICENSE ├── README.md ├── dgs-client ├── .gitignore ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ └── main │ ├── java │ └── com │ │ └── example │ │ └── demo │ │ └── DemoApplication.java │ └── resources │ ├── application.properties │ └── schema │ └── schema.graphql ├── dgs-codegen ├── .gitignore ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DataInitializer.java │ │ │ ├── DemoApplication.java │ │ │ ├── gql │ │ │ ├── CustomCodeRegistry.java │ │ │ ├── CustomDataFetchingExceptionHandler.java │ │ │ ├── CustomRuntimeWiring.java │ │ │ ├── CustomTypeDefinitionRegistryConfig.java │ │ │ ├── datafetcher │ │ │ │ └── PostsDataFetcher.java │ │ │ ├── dataloaders │ │ │ │ ├── AuthorsDataLoader.java │ │ │ │ └── CommentsDataLoader.java │ │ │ ├── directives │ │ │ │ └── UppercaseDirectiveWiring.java │ │ │ └── scalars │ │ │ │ ├── LocalDateTimeScalar.java │ │ │ │ └── UUIDScalar.java │ │ │ ├── model │ │ │ ├── AuthorEntity.java │ │ │ ├── CommentEntity.java │ │ │ └── PostEntity.java │ │ │ ├── repository │ │ │ ├── AuthorRepository.java │ │ │ ├── CommentRepository.java │ │ │ └── PostRepository.java │ │ │ └── service │ │ │ ├── AuthorNotFoundException.java │ │ │ ├── AuthorService.java │ │ │ ├── PostNotFoundException.java │ │ │ └── PostService.java │ └── resources │ │ ├── application.properties │ │ ├── schema.sql │ │ └── schema │ │ └── schema.graphql │ └── test │ └── java │ └── com │ └── example │ └── demo │ ├── MutationTests.java │ └── QueryTests.java ├── dgs-fileupload ├── .gitignore ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DemoApplication.java │ │ │ └── gql │ │ │ ├── FileUploadInput.java │ │ │ └── FileUploadMutation.java │ └── resources │ │ ├── application.properties │ │ └── schema │ │ └── schema.graphql │ └── test │ └── java │ └── com │ └── example │ └── demo │ └── DemoApplicationTests.java ├── dgs-kotlin-co ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DemoApplication.kt │ │ │ ├── Extensions.kt │ │ │ ├── gql │ │ │ ├── ExceptionHandlers.kt │ │ │ ├── datafetcher │ │ │ │ ├── AuthorsDataFetcher.kt │ │ │ │ └── PostsDataFetcher.kt │ │ │ ├── dataloader │ │ │ │ ├── AuthorsDataLoader.kt │ │ │ │ └── CommentsDataLoader.kt │ │ │ └── scalar │ │ │ │ ├── LocalDateTimeScalar.kt │ │ │ │ └── UUIDScalar.kt │ │ │ ├── model │ │ │ ├── AuthorEntity.kt │ │ │ ├── CommentEntity.kt │ │ │ ├── PostEntity.kt │ │ │ └── PostStatus.kt │ │ │ ├── repository │ │ │ ├── AuthorRepository.kt │ │ │ ├── CommentRepository.kt │ │ │ └── PostRepository.kt │ │ │ └── service │ │ │ ├── AuthorNotFoundException.kt │ │ │ ├── AuthorService.kt │ │ │ ├── DefaultPostService.kt │ │ │ ├── PostNotFoundException.kt │ │ │ └── PostService.kt │ └── resources │ │ ├── application.properties │ │ ├── schema.sql │ │ └── schema │ │ └── schema.graphql │ └── test │ └── kotlin │ └── com │ └── example │ └── demo │ ├── IntegrationTests.kt │ ├── MutationTests.kt │ ├── QueryTests.kt │ └── SubscriptionTests.kt ├── dgs-kotlin ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DemoApplication.kt │ │ │ ├── Extensions.kt │ │ │ ├── gql │ │ │ ├── ExceptionHandlers.kt │ │ │ ├── datafetchers │ │ │ │ ├── AuthDataFetcher.kt │ │ │ │ ├── AuthorsDataFetcher.kt │ │ │ │ └── PostsDataFetcher.kt │ │ │ ├── dataloaders │ │ │ │ ├── AuthorsDataLoader.kt │ │ │ │ └── CommentsDataLoader.kt │ │ │ └── scalars │ │ │ │ ├── LocalDateTimeScalar.kt │ │ │ │ └── UUIDScalar.kt │ │ │ ├── model │ │ │ ├── AuthorEntity.kt │ │ │ ├── CommentEntity.kt │ │ │ ├── PostEntity.kt │ │ │ ├── PostStatus.kt │ │ │ └── ProfileEntity.kt │ │ │ ├── repository │ │ │ ├── AuthorRepository.kt │ │ │ ├── CommentRepository.kt │ │ │ ├── PostRepository.kt │ │ │ └── ProfileRepository.kt │ │ │ └── service │ │ │ ├── AuthorNotFoundException.kt │ │ │ ├── AuthorService.kt │ │ │ ├── PostNotFoundException.kt │ │ │ └── PostService.kt │ └── resources │ │ ├── application.properties │ │ ├── data.sql │ │ ├── schema.sql │ │ └── schema │ │ └── schema.graphql │ └── test │ └── kotlin │ └── com │ └── example │ └── demo │ ├── MutationTests.kt │ ├── QueryTests.kt │ ├── SubscriptionTests.kt │ └── TestConfigInitializer.kt ├── dgs-subscription-sse ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DataFetchers.kt │ │ │ ├── DemoApplication.kt │ │ │ └── Scalars.kt │ └── resources │ │ ├── application.properties │ │ └── schema │ │ └── schema.graphql │ └── test │ └── kotlin │ └── com │ └── example │ └── demo │ ├── IntegrationTests.kt │ └── SubscriptionTest.kt ├── dgs-subscription-ui ├── .editorconfig ├── .gitignore ├── angular.json ├── karma.conf.js ├── package.json ├── src │ ├── app │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ └── graphql.module.ts │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.css │ └── test.ts ├── tsconfig.app.json ├── tsconfig.json └── tsconfig.spec.json ├── dgs-subscription-ws ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DataFetchers.kt │ │ │ ├── DemoApplication.kt │ │ │ └── Scalars.kt │ └── resources │ │ ├── application.properties │ │ └── schema │ │ └── schema.graphql │ └── test │ └── kotlin │ └── com │ └── example │ └── demo │ ├── IntegrationTests.kt │ └── SubscriptionTest.kt ├── dgs-webflux ├── .gitignore ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DataInitializer.java │ │ │ ├── DemoApplication.java │ │ │ ├── gql │ │ │ ├── CustomExceptionHandlers.java │ │ │ ├── datafetchers │ │ │ │ └── PostsDataFetcher.java │ │ │ ├── dataloaders │ │ │ │ ├── AuthorsDataLoader.java │ │ │ │ └── CommentsDataLoader.java │ │ │ └── types │ │ │ │ ├── Author.java │ │ │ │ ├── Comment.java │ │ │ │ ├── CommentInput.java │ │ │ │ ├── CreatePostInput.java │ │ │ │ └── Post.java │ │ │ ├── model │ │ │ ├── AuthorEntity.java │ │ │ ├── CommentEntity.java │ │ │ └── PostEntity.java │ │ │ ├── repository │ │ │ ├── AuthorRepository.java │ │ │ ├── CommentRepository.java │ │ │ └── PostRepository.java │ │ │ └── service │ │ │ ├── AuthorNotFoundException.java │ │ │ ├── AuthorService.java │ │ │ ├── PostNotFoundException.java │ │ │ └── PostService.java │ └── resources │ │ ├── application.properties │ │ ├── schema.sql │ │ └── schema │ │ └── schema.graphql │ └── test │ └── java │ └── com │ └── example │ └── demo │ ├── IntegrationTests.java │ ├── MutationTests.java │ ├── QueryTests.java │ └── SubscriptionTests.java ├── dgs ├── .gitignore ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DataInitializer.java │ │ │ ├── DemoApplication.java │ │ │ ├── gql │ │ │ ├── CustomDataFetchingExceptionHandler.java │ │ │ ├── datafetchers │ │ │ │ └── PostsDataFetcher.java │ │ │ ├── dataloaders │ │ │ │ ├── AuthorsDataLoader.java │ │ │ │ └── CommentsDataLoader.java │ │ │ └── types │ │ │ │ ├── Author.java │ │ │ │ ├── Comment.java │ │ │ │ ├── CommentInput.java │ │ │ │ ├── CreatePostInput.java │ │ │ │ ├── Post.java │ │ │ │ └── PostStatus.java │ │ │ ├── model │ │ │ ├── AuthorEntity.java │ │ │ ├── CommentEntity.java │ │ │ └── PostEntity.java │ │ │ ├── repository │ │ │ ├── AuthorRepository.java │ │ │ ├── CommentRepository.java │ │ │ └── PostRepository.java │ │ │ └── service │ │ │ ├── AuthorNotFoundException.java │ │ │ ├── AuthorService.java │ │ │ ├── PostNotFoundException.java │ │ │ └── PostService.java │ └── resources │ │ ├── application.properties │ │ ├── schema.sql │ │ └── schema │ │ └── schema.graphql │ └── test │ └── java │ └── com │ └── example │ └── demo │ ├── MutationTests.java │ └── QueryTests.java ├── docker-compose.yml ├── docs ├── adv.md ├── sec.md ├── ui-allPosts.png ├── ui-createPost.png └── ui-postById.png ├── graphql-kotlin ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DemoApplication.kt │ │ │ ├── Extensions.kt │ │ │ ├── ValidationConfig.kt │ │ │ ├── gql │ │ │ ├── CustomSchemaGeneratorHooks.kt │ │ │ ├── GqlConfig.kt │ │ │ ├── datafetchers │ │ │ │ ├── DataLoaders.kt │ │ │ │ ├── Mutations.kt │ │ │ │ ├── Queries.kt │ │ │ │ └── Subscriptions.kt │ │ │ ├── directives │ │ │ │ ├── UpperCase.kt │ │ │ │ └── UpperCaseDirectiveWiring.kt │ │ │ ├── exceptions │ │ │ │ ├── CustomDataFetcherExceptionHandler.kt │ │ │ │ └── ValidationException.kt │ │ │ ├── scalars │ │ │ │ ├── LocalDateTimeScalar.kt │ │ │ │ ├── Scalars.kt │ │ │ │ └── UUIDScalar.kt │ │ │ └── types │ │ │ │ ├── Author.kt │ │ │ │ ├── Comment.kt │ │ │ │ ├── CommentInput.kt │ │ │ │ ├── CreatePostInput.kt │ │ │ │ └── Post.kt │ │ │ ├── model │ │ │ ├── AuthorEntity.kt │ │ │ ├── CommentEntity.kt │ │ │ ├── PostEntity.kt │ │ │ └── PostStatus.kt │ │ │ ├── repository │ │ │ ├── AuthorRepository.kt │ │ │ ├── CommentRepository.kt │ │ │ └── PostRepository.kt │ │ │ └── service │ │ │ ├── AuthorNotFoundException.kt │ │ │ ├── AuthorService.kt │ │ │ ├── DefaultPostService.kt │ │ │ ├── PostNotFoundException.kt │ │ │ └── PostService.kt │ └── resources │ │ ├── application.properties │ │ └── schema.sql │ └── test │ └── kotlin │ └── com │ └── example │ └── demo │ └── DemoApplicationTests.kt ├── legacy ├── graphql-java-kickstart-annotations │ ├── .gitignore │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── demo │ │ │ │ ├── DataInitializer.java │ │ │ │ ├── DemoApplication.java │ │ │ │ ├── gql │ │ │ │ ├── CustomExceptionHandler.java │ │ │ │ ├── dataloaders │ │ │ │ │ ├── AuthorsDataLoader.java │ │ │ │ │ ├── CommentsDataLoader.java │ │ │ │ │ └── DataLoadersConfig.java │ │ │ │ ├── directives │ │ │ │ │ ├── UpperCaseDirective.java │ │ │ │ │ └── UpperCaseDirectiveWiring.java │ │ │ │ ├── resolvers │ │ │ │ │ ├── AuthorDataFetcher.java │ │ │ │ │ ├── CommentsDataFetcher.java │ │ │ │ │ ├── Mutations.java │ │ │ │ │ └── Queries.java │ │ │ │ ├── scalars │ │ │ │ │ ├── LocalDateTimeScalar.java │ │ │ │ │ ├── ScalarConfig.java │ │ │ │ │ └── UUIDScalar.java │ │ │ │ └── types │ │ │ │ │ ├── Author.java │ │ │ │ │ ├── Comment.java │ │ │ │ │ ├── CommentInput.java │ │ │ │ │ ├── CreatePostInput.java │ │ │ │ │ ├── Post.java │ │ │ │ │ └── PostStatus.java │ │ │ │ ├── model │ │ │ │ ├── AuthorEntity.java │ │ │ │ ├── CommentEntity.java │ │ │ │ └── PostEntity.java │ │ │ │ ├── repository │ │ │ │ ├── AuthorRepository.java │ │ │ │ ├── CommentRepository.java │ │ │ │ └── PostRepository.java │ │ │ │ └── service │ │ │ │ ├── AuthorNotFoundException.java │ │ │ │ ├── AuthorService.java │ │ │ │ ├── PostNotFoundException.java │ │ │ │ └── PostService.java │ │ └── resources │ │ │ ├── application.properties │ │ │ └── schema.sql │ │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ └── demo │ │ └── PostsQueryTests.java ├── graphql-java-kickstart-webclient │ ├── .gitignore │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DemoApplication.java │ │ │ └── gql │ │ │ └── types │ │ │ ├── Author.java │ │ │ ├── Comment.java │ │ │ ├── CommentInput.java │ │ │ ├── CreatePostInput.java │ │ │ ├── Post.java │ │ │ └── PostStatus.java │ │ └── resources │ │ ├── application.properties │ │ ├── fileupload.gql │ │ └── test.txt ├── graphql-java-kickstart │ ├── .gitignore │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── demo │ │ │ │ ├── DataInitializer.java │ │ │ │ ├── DemoApplication.java │ │ │ │ ├── gql │ │ │ │ ├── CustomExceptionHandler.java │ │ │ │ ├── dataloaders │ │ │ │ │ ├── AuthorsDataLoader.java │ │ │ │ │ ├── CommentsDataLoader.java │ │ │ │ │ └── DataLoadersConfig.java │ │ │ │ ├── directives │ │ │ │ │ ├── DirectiveConfig.java │ │ │ │ │ └── UppercaseDirective.java │ │ │ │ ├── resolvers │ │ │ │ │ ├── AddCommentMutationResolver.java │ │ │ │ │ ├── AllPostQueryResolver.java │ │ │ │ │ ├── AuthorResolver.java │ │ │ │ │ ├── CommentAddedSubscriptionResolver.java │ │ │ │ │ ├── CommentsResolver.java │ │ │ │ │ ├── CreatePostMutationResolver.java │ │ │ │ │ ├── PostByIdQueryResolver.java │ │ │ │ │ └── UploadFileMutationResolver.java │ │ │ │ ├── scalars │ │ │ │ │ ├── LocalDateTimeScalar.java │ │ │ │ │ ├── ScalarConfig.java │ │ │ │ │ └── UUIDScalar.java │ │ │ │ └── types │ │ │ │ │ ├── Author.java │ │ │ │ │ ├── Comment.java │ │ │ │ │ ├── CommentInput.java │ │ │ │ │ ├── CreatePostInput.java │ │ │ │ │ ├── Post.java │ │ │ │ │ └── PostStatus.java │ │ │ │ ├── model │ │ │ │ ├── AuthorEntity.java │ │ │ │ ├── CommentEntity.java │ │ │ │ └── PostEntity.java │ │ │ │ ├── repository │ │ │ │ ├── AuthorRepository.java │ │ │ │ ├── CommentRepository.java │ │ │ │ └── PostRepository.java │ │ │ │ └── service │ │ │ │ ├── AuthorNotFoundException.java │ │ │ │ ├── AuthorService.java │ │ │ │ ├── PostNotFoundException.java │ │ │ │ └── PostService.java │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── schema.sql │ │ │ └── schema │ │ │ └── schema.graphql │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ └── DemoApplicationTests.java │ │ └── resources │ │ └── test.txt ├── graphql-java │ ├── .gitignore │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── demo │ │ │ │ ├── DataInitializer.java │ │ │ │ ├── DemoApplication.java │ │ │ │ ├── gql │ │ │ │ ├── CustomDataFetchingExceptionHandler.java │ │ │ │ ├── DataFetchers.java │ │ │ │ ├── DataLoaders.java │ │ │ │ ├── GraphQLConfig.java │ │ │ │ ├── directives │ │ │ │ │ └── UpperCaseDirectiveWiring.java │ │ │ │ ├── scalars │ │ │ │ │ ├── LocalDateTimeScalar.java │ │ │ │ │ ├── Scalars.java │ │ │ │ │ └── UUIDScalar.java │ │ │ │ └── types │ │ │ │ │ ├── Author.java │ │ │ │ │ ├── Comment.java │ │ │ │ │ ├── CommentInput.java │ │ │ │ │ ├── CreatePostInput.java │ │ │ │ │ ├── Post.java │ │ │ │ │ └── PostStatus.java │ │ │ │ ├── model │ │ │ │ ├── AuthorEntity.java │ │ │ │ ├── CommentEntity.java │ │ │ │ └── PostEntity.java │ │ │ │ ├── repository │ │ │ │ ├── AuthorRepository.java │ │ │ │ ├── CommentRepository.java │ │ │ │ └── PostRepository.java │ │ │ │ └── service │ │ │ │ ├── AuthorNotFoundException.java │ │ │ │ ├── AuthorService.java │ │ │ │ ├── PostNotFoundException.java │ │ │ │ └── PostService.java │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── schema.sql │ │ │ └── schema │ │ │ └── schema.graphql │ │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ └── demo │ │ └── DemoApplicationTests.java └── graphql-spqr │ ├── .gitignore │ ├── build.gradle │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DataInitializer.java │ │ │ ├── DemoApplication.java │ │ │ ├── gql │ │ │ ├── CustomDataFetchingExceptionHandler.java │ │ │ ├── datafetcher │ │ │ │ └── PostsDataFetcher.java │ │ │ ├── dataloaders │ │ │ │ ├── AuthorsDataLoader.java │ │ │ │ ├── CommentsDataLoader.java │ │ │ │ └── SimpleDataLoaderRegistryFactory.java │ │ │ └── types │ │ │ │ ├── Author.java │ │ │ │ ├── Comment.java │ │ │ │ ├── CreateComment.java │ │ │ │ ├── CreatePost.java │ │ │ │ ├── Post.java │ │ │ │ └── PostStatus.java │ │ │ ├── model │ │ │ ├── AuthorEntity.java │ │ │ ├── CommentEntity.java │ │ │ └── PostEntity.java │ │ │ ├── repository │ │ │ ├── AuthorRepository.java │ │ │ ├── CommentRepository.java │ │ │ └── PostRepository.java │ │ │ └── service │ │ │ ├── AuthorNotFoundException.java │ │ │ ├── AuthorService.java │ │ │ ├── PostNotFoundException.java │ │ │ └── PostService.java │ └── resources │ │ ├── application.properties │ │ └── schema.sql │ └── test │ └── java │ └── com │ └── example │ └── demo │ ├── MutationTests.java │ ├── QueryMockTests.java │ ├── QueryTests.java │ ├── SseSubscriptionTests.java │ └── WebSocketSubscriptionTests.java ├── pg-initdb.d └── init.sql ├── spring-graphql-querydsl ├── .gitignore ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DataInitializer.java │ │ │ ├── DemoApplication.java │ │ │ ├── gql │ │ │ ├── PostsRuntimeWiring.java │ │ │ ├── directives │ │ │ │ └── UpperCaseDirectiveWiring.java │ │ │ └── scalars │ │ │ │ ├── LocalDateTimeScalar.java │ │ │ │ ├── Scalars.java │ │ │ │ └── UUIDScalar.java │ │ │ ├── model │ │ │ ├── Comment.java │ │ │ ├── Post.java │ │ │ └── PostStatus.java │ │ │ └── repository │ │ │ ├── CommentRepository.java │ │ │ └── PostRepository.java │ └── resources │ │ ├── application.properties │ │ ├── graphql │ │ └── schema.graphqls │ │ └── schema.sql │ └── test │ └── java │ └── com │ └── example │ └── demo │ └── QueryTests.java ├── spring-graphql-rsocket-kotlin-co ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DemoApplication.kt │ │ │ ├── Entities.kt │ │ │ ├── Extensions.kt │ │ │ ├── Repositories.kt │ │ │ ├── Services.kt │ │ │ └── gql │ │ │ ├── ExceptionHandlers.kt │ │ │ ├── PostsRuntimeWiring.kt │ │ │ ├── datafetchers │ │ │ └── PostController.kt │ │ │ ├── directives │ │ │ └── UpperCaseDirectiveWiring.kt │ │ │ ├── scalars │ │ │ ├── LocalDateTimeScalar.kt │ │ │ ├── Scalars.kt │ │ │ └── UUIDScalar.kt │ │ │ └── types │ │ │ └── Models.kt │ └── resources │ │ ├── application.properties │ │ ├── graphql │ │ └── schema.graphqls │ │ └── schema.sql │ └── test │ └── kotlin │ └── com │ └── example │ └── demo │ ├── IntegrationTests.kt │ ├── MutationTests.kt │ └── QueryTests.kt ├── spring-graphql-webflux ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DataInitializer.java │ │ │ ├── DemoApplication.java │ │ │ ├── gql │ │ │ ├── ExceptionHandlers.java │ │ │ ├── datafetchers │ │ │ │ └── PostsDataFetcherController.java │ │ │ └── types │ │ │ │ ├── Author.java │ │ │ │ ├── Comment.java │ │ │ │ ├── CommentInput.java │ │ │ │ ├── CreatePostInput.java │ │ │ │ └── Post.java │ │ │ ├── model │ │ │ ├── AuthorEntity.java │ │ │ ├── CommentEntity.java │ │ │ └── PostEntity.java │ │ │ ├── repository │ │ │ ├── AuthorRepository.java │ │ │ ├── CommentRepository.java │ │ │ └── PostRepository.java │ │ │ └── service │ │ │ ├── AuthorNotFoundException.java │ │ │ ├── AuthorService.java │ │ │ ├── PostNotFoundException.java │ │ │ └── PostService.java │ └── resources │ │ ├── application.properties │ │ ├── graphql │ │ └── schema.graphqls │ │ └── schema.sql │ └── test │ └── java │ └── com │ └── example │ └── demo │ ├── IntegrationTests.java │ ├── MutationTests.java │ ├── QueryTests.java │ ├── SubscriptionTests.java │ └── SubscriptionTestsWithWebSocketGraphqlTester.java ├── spring-graphql-webmvc ├── .gitignore ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DataInitializer.java │ │ │ ├── DemoApplication.java │ │ │ ├── gql │ │ │ ├── ExceptionHandlers.java │ │ │ ├── PostController.java │ │ │ └── types │ │ │ │ ├── Author.java │ │ │ │ ├── Comment.java │ │ │ │ ├── CommentInput.java │ │ │ │ ├── CreatePostInput.java │ │ │ │ ├── Post.java │ │ │ │ └── PostStatus.java │ │ │ ├── model │ │ │ ├── AuthorEntity.java │ │ │ ├── CommentEntity.java │ │ │ └── PostEntity.java │ │ │ ├── repository │ │ │ ├── AuthorRepository.java │ │ │ ├── CommentRepository.java │ │ │ └── PostRepository.java │ │ │ └── service │ │ │ ├── AuthorNotFoundException.java │ │ │ ├── AuthorService.java │ │ │ ├── PostNotFoundException.java │ │ │ └── PostService.java │ └── resources │ │ ├── application.properties │ │ ├── graphql │ │ └── schema.graphqls │ │ └── schema.sql │ └── test │ ├── java │ └── com │ │ └── example │ │ └── demo │ │ ├── IntegrationTests.java │ │ ├── MutationTests.java │ │ ├── QueryTests.java │ │ ├── SubscriptionTests.java │ │ ├── SubscriptionTestsWithWebSocketGraphqlTester.java │ │ └── TestDemoApplication.java │ └── resources │ └── init.sql └── spring-graphql ├── .gitignore ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src ├── main ├── java │ └── com │ │ └── example │ │ └── demo │ │ ├── DataInitializer.java │ │ ├── DemoApplication.java │ │ ├── gql │ │ ├── DataFetchers.java │ │ ├── DataLoaders.java │ │ ├── DataLoadersConfig.java │ │ ├── ExceptionHandlers.java │ │ ├── PostsRuntimeWiring.java │ │ ├── directives │ │ │ └── UpperCaseDirectiveWiring.java │ │ ├── scalars │ │ │ ├── LocalDateTimeScalar.java │ │ │ ├── Scalars.java │ │ │ └── UUIDScalar.java │ │ └── types │ │ │ ├── Author.java │ │ │ ├── Comment.java │ │ │ ├── CommentInput.java │ │ │ ├── CreatePostInput.java │ │ │ ├── Post.java │ │ │ └── PostStatus.java │ │ ├── model │ │ ├── AuthorEntity.java │ │ ├── CommentEntity.java │ │ └── PostEntity.java │ │ ├── repository │ │ ├── AuthorRepository.java │ │ ├── CommentRepository.java │ │ └── PostRepository.java │ │ └── service │ │ ├── AuthorNotFoundException.java │ │ ├── AuthorService.java │ │ ├── PostNotFoundException.java │ │ └── PostService.java └── resources │ ├── application.properties │ ├── data.sql │ ├── graphql │ └── schema.graphqls │ └── schema.sql └── test └── java └── com └── example └── demo ├── QueryTests.java └── SubscriptionTests.java /.github/workflows/dgs-client.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: dgs-client 5 | 6 | on: 7 | push: 8 | paths: 9 | - "dgs-client/**" 10 | branches: [ master ] 11 | pull_request: 12 | paths: 13 | - "dgs-client/**" 14 | types: 15 | - opened 16 | - synchronize 17 | - reopened 18 | 19 | jobs: 20 | build: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Set up JDK 25 | uses: actions/setup-java@v4 26 | with: 27 | java-version: '21' 28 | distribution: 'temurin' 29 | - name: Build with Gradle 30 | run: | 31 | cd dgs-client 32 | chmod +x gradlew 33 | ./gradlew build 34 | 35 | -------------------------------------------------------------------------------- /.github/workflows/dgs-codegen.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: dgs-codegen 5 | 6 | on: 7 | push: 8 | paths: 9 | - "dgs-codegen/**" 10 | branches: [ master ] 11 | pull_request: 12 | paths: 13 | - "dgs-codegen/**" 14 | types: 15 | - opened 16 | - synchronize 17 | - reopened 18 | 19 | jobs: 20 | 21 | build: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v4 25 | - name: Set up JDK 26 | uses: actions/setup-java@v4 27 | with: 28 | java-version: '21' 29 | distribution: 'temurin' 30 | - name: Setup Postgres in Docker 31 | run: | 32 | docker compose up -d postgres 33 | docker ps -a 34 | - name: Build with Gradle 35 | run: | 36 | cd dgs-codegen 37 | chmod +x gradlew 38 | ./gradlew build 39 | 40 | -------------------------------------------------------------------------------- /.github/workflows/dgs-fileupload.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: dgs-fileupload 5 | 6 | on: 7 | push: 8 | paths: 9 | - "dgs-fileupload/**" 10 | branches: [ master ] 11 | pull_request: 12 | paths: 13 | - "dgs-fileupload/**" 14 | types: 15 | - opened 16 | - synchronize 17 | - reopened 18 | 19 | jobs: 20 | 21 | build: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v4 25 | - name: Set up JDK 26 | uses: actions/setup-java@v4 27 | with: 28 | java-version: '21' 29 | distribution: 'temurin' 30 | - name: Build with Gradle 31 | run: | 32 | cd dgs-fileupload 33 | chmod +x gradlew 34 | ./gradlew build 35 | 36 | -------------------------------------------------------------------------------- /.github/workflows/dgs-kotlin-co.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: dgs-kotlin-co 5 | 6 | on: 7 | push: 8 | paths: 9 | - "dgs-kotlin-co/**" 10 | branches: [ master ] 11 | pull_request: 12 | paths: 13 | - "dgs-kotlin-co/**" 14 | types: 15 | - opened 16 | - synchronize 17 | - reopened 18 | 19 | jobs: 20 | 21 | build: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v4 25 | - name: Set up JDK 26 | uses: actions/setup-java@v4 27 | with: 28 | java-version: '21' 29 | distribution: 'temurin' 30 | - name: Setup Postgres in Docker 31 | run: | 32 | docker compose up -d postgres 33 | docker ps -a 34 | - name: Build with Gradle 35 | run: | 36 | cd dgs-kotlin-co 37 | chmod +x gradlew 38 | ./gradlew build 39 | -------------------------------------------------------------------------------- /.github/workflows/dgs-kotlin.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: dgs-kotlin 5 | 6 | on: 7 | push: 8 | paths: 9 | - "dgs-kotlin/**" 10 | branches: [ master ] 11 | pull_request: 12 | paths: 13 | - "dgs-kotlin/**" 14 | types: 15 | - opened 16 | - synchronize 17 | - reopened 18 | 19 | jobs: 20 | 21 | build: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v4 25 | - name: Set up JDK 26 | uses: actions/setup-java@v4 27 | with: 28 | java-version: '21' 29 | distribution: 'temurin' 30 | - name: Setup Postgres in Docker 31 | run: | 32 | docker compose up -d 33 | sleep 5 34 | docker ps -a 35 | - name: Build with Gradle 36 | run: | 37 | cd dgs-kotlin 38 | chmod +x gradlew 39 | ./gradlew build 40 | -------------------------------------------------------------------------------- /.github/workflows/dgs-subscription-sse.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: dgs-subscription-sse 5 | 6 | on: 7 | push: 8 | paths: 9 | - "dgs-subscription-sse/**" 10 | branches: [ master ] 11 | pull_request: 12 | paths: 13 | - "dgs-subscription-sse/**" 14 | types: 15 | - opened 16 | - synchronize 17 | - reopened 18 | 19 | jobs: 20 | 21 | build: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v4 25 | - name: Set up JDK 26 | uses: actions/setup-java@v4 27 | with: 28 | java-version: '21' 29 | distribution: 'temurin' 30 | - name: Build with Gradle 31 | run: | 32 | cd dgs-subscription-sse 33 | chmod +x gradlew 34 | ./gradlew build 35 | 36 | -------------------------------------------------------------------------------- /.github/workflows/dgs-subscription-ws.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: dgs-subscription-ws 5 | 6 | on: 7 | push: 8 | paths: 9 | - "dgs-subscription-ws/**" 10 | branches: [ master ] 11 | pull_request: 12 | paths: 13 | - "dgs-subscription-ws/**" 14 | types: 15 | - opened 16 | - synchronize 17 | - reopened 18 | 19 | jobs: 20 | 21 | build: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v4 25 | - name: Set up JDK 26 | uses: actions/setup-java@v4 27 | with: 28 | java-version: '21' 29 | distribution: 'temurin' 30 | - name: Build with Gradle 31 | run: | 32 | cd dgs-subscription-ws 33 | chmod +x gradlew 34 | ./gradlew build 35 | 36 | -------------------------------------------------------------------------------- /.github/workflows/dgs-webflux.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: dgs-webflux 5 | 6 | on: 7 | push: 8 | paths: 9 | - "dgs-webflux/**" 10 | branches: [ master ] 11 | pull_request: 12 | paths: 13 | - "dgs-webflux/**" 14 | types: 15 | - opened 16 | - synchronize 17 | - reopened 18 | 19 | jobs: 20 | 21 | build: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v4 25 | - name: Set up JDK 26 | uses: actions/setup-java@v4 27 | with: 28 | java-version: '21' 29 | distribution: 'temurin' 30 | - name: Setup Postgres in Docker 31 | run: | 32 | docker compose up -d postgres 33 | sleep 5 34 | docker ps -a 35 | - name: Build with Gradle 36 | run: | 37 | cd dgs-webflux 38 | chmod +x gradlew 39 | ./gradlew build 40 | 41 | 42 | -------------------------------------------------------------------------------- /.github/workflows/dgs.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: dgs 5 | 6 | on: 7 | push: 8 | paths: 9 | - "dgs/**" 10 | branches: [ master ] 11 | pull_request: 12 | paths: 13 | - "dgs/**" 14 | types: 15 | - opened 16 | - synchronize 17 | - reopened 18 | 19 | jobs: 20 | 21 | build: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v4 25 | - name: Set up JDK 26 | uses: actions/setup-java@v4 27 | with: 28 | java-version: '21' 29 | distribution: 'temurin' 30 | - name: Setup Postgres in Docker 31 | run: | 32 | docker compose up -d postgres 33 | docker ps -a 34 | - name: Build with Gradle 35 | run: | 36 | cd dgs 37 | chmod +x gradlew 38 | ./gradlew build 39 | 40 | -------------------------------------------------------------------------------- /.github/workflows/graphql-kotlin.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: graphql-kotlin 5 | 6 | on: 7 | push: 8 | paths: 9 | - "graphql-kotlin/**" 10 | branches: [ master ] 11 | pull_request: 12 | paths: 13 | - "graphql-kotlin/**" 14 | types: 15 | - opened 16 | - synchronize 17 | - reopened 18 | 19 | jobs: 20 | 21 | 22 | build: 23 | runs-on: ubuntu-latest 24 | steps: 25 | - uses: actions/checkout@v4 26 | - name: Set up JDK 27 | uses: actions/setup-java@v4 28 | with: 29 | java-version: '21' 30 | distribution: 'temurin' 31 | - name: Setup Postgres in Docker 32 | run: | 33 | docker compose up -d postgres 34 | docker ps -a 35 | - name: Build with Gradle 36 | run: | 37 | cd graphql-kotlin 38 | chmod +x gradlew 39 | ./gradlew build 40 | 41 | 42 | -------------------------------------------------------------------------------- /.github/workflows/legacy-graphql-java.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: legacy-graphql-java 5 | 6 | on: 7 | push: 8 | paths: 9 | - "legacy/graphql-java/**" 10 | branches: [ master ] 11 | pull_request: 12 | paths: 13 | - "legacy/graphql-java/**" 14 | types: 15 | - opened 16 | - synchronize 17 | - reopened 18 | 19 | jobs: 20 | 21 | 22 | build: 23 | runs-on: ubuntu-latest 24 | steps: 25 | - uses: actions/checkout@v4 26 | - name: Set up JDK 27 | uses: actions/setup-java@v4 28 | with: 29 | java-version: '17' 30 | distribution: 'temurin' 31 | - name: Setup Postgres in Docker 32 | run: | 33 | docker compose up -d postgres 34 | docker ps -a 35 | - name: Build with Gradle 36 | run: | 37 | cd legacy/graphql-java 38 | chmod +x gradlew 39 | ./gradlew build 40 | 41 | 42 | -------------------------------------------------------------------------------- /.github/workflows/legacy-graphql-spqr.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: legacy-graphql-spqr 5 | 6 | on: 7 | push: 8 | paths: 9 | - "legacy/graphql-spqr/**" 10 | branches: [ master ] 11 | pull_request: 12 | paths: 13 | - "legacy/graphql-spqr/**" 14 | types: 15 | - opened 16 | - synchronize 17 | - reopened 18 | 19 | jobs: 20 | build: 21 | 22 | runs-on: ubuntu-latest 23 | 24 | steps: 25 | - uses: actions/checkout@v4 26 | - name: Set up JDK 27 | uses: actions/setup-java@v4 28 | with: 29 | java-version: '21' 30 | distribution: 'temurin' 31 | - name: Setup Postgres in Docker 32 | run: | 33 | docker compose up -d postgres 34 | docker ps -a 35 | - name: Build with Gradle 36 | run: | 37 | cd legacy/graphql-spqr 38 | chmod +x gradlew 39 | ./gradlew build 40 | 41 | 42 | -------------------------------------------------------------------------------- /.github/workflows/spring-graphql.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: spring-graphql 5 | 6 | on: 7 | push: 8 | paths: 9 | - "spring-graphql/**" 10 | branches: [ master ] 11 | pull_request: 12 | paths: 13 | - "spring-graphql/**" 14 | types: 15 | - opened 16 | - synchronize 17 | - reopened 18 | 19 | jobs: 20 | build: 21 | 22 | runs-on: ubuntu-latest 23 | 24 | steps: 25 | - uses: actions/checkout@v4 26 | - name: Set up JDK 27 | uses: actions/setup-java@v4 28 | with: 29 | java-version: '21' 30 | distribution: 'temurin' 31 | - name: Setup Postgres in Docker 32 | run: | 33 | docker compose up -d postgres 34 | docker ps -a 35 | - name: Build with Gradle 36 | run: | 37 | cd spring-graphql 38 | chmod +x gradlew 39 | ./gradlew build 40 | 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | depdendencies/ 25 | data/ 26 | 27 | HELP.md 28 | .gradle 29 | build/ 30 | 31 | ### STS ### 32 | .apt_generated 33 | .classpath 34 | .factorypath 35 | .project 36 | .settings 37 | .springBeans 38 | .sts4-cache 39 | bin/ 40 | !**/src/main/**/bin/ 41 | !**/src/test/**/bin/ 42 | 43 | ### IntelliJ IDEA ### 44 | .idea 45 | *.iws 46 | *.iml 47 | *.ipr 48 | out/ 49 | !**/src/main/**/out/ 50 | !**/src/test/**/out/ 51 | 52 | ### NetBeans ### 53 | /nbproject/private/ 54 | /nbbuild/ 55 | /dist/ 56 | /nbdist/ 57 | /.nb-gradle/ 58 | 59 | ### VS Code ### 60 | .vscode/ 61 | -------------------------------------------------------------------------------- /dgs-client/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /dgs-client/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/dgs-client/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /dgs-client/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /dgs-client/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://repo.spring.io/milestone' } 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = 'dgs-client-example' 9 | -------------------------------------------------------------------------------- /dgs-client/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | graphql.client.url=http://localhost:8080/graphql 2 | # 3 | # Logging level 4 | # 5 | logging.level.com.example=DEBUG 6 | -------------------------------------------------------------------------------- /dgs-client/src/main/resources/schema/schema.graphql: -------------------------------------------------------------------------------- 1 | type Post{ 2 | id: ID! 3 | title: String! 4 | content: String 5 | comments: [Comment] 6 | status: PostStatus 7 | createdAt: LocalDateTime 8 | authorId:String 9 | author:Author 10 | } 11 | 12 | 13 | type Author{ 14 | id:ID! 15 | name:String! 16 | email:String! 17 | createdAt: LocalDateTime 18 | posts: [Post] 19 | } 20 | type Comment{ 21 | id: ID! 22 | content: String! 23 | createdAt: LocalDateTime 24 | postId: String! 25 | } 26 | 27 | input CreatePostInput { 28 | title: String! 29 | content: String! 30 | } 31 | 32 | input CommentInput{ 33 | postId: String! 34 | content: String! 35 | } 36 | 37 | type Query { 38 | allPosts: [Post!]! 39 | postById(postId: String!): Post 40 | } 41 | 42 | type Mutation { 43 | createPost(createPostInput: CreatePostInput!): UUID! 44 | } 45 | 46 | enum PostStatus { 47 | DRAFT, PENDING_MODERATION, PUBLISHED 48 | } 49 | 50 | scalar LocalDateTime 51 | scalar UUID 52 | -------------------------------------------------------------------------------- /dgs-codegen/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /dgs-codegen/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/dgs-codegen/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /dgs-codegen/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /dgs-codegen/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://repo.spring.io/milestone' } 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = 'dgs-codegen' 9 | -------------------------------------------------------------------------------- /dgs-codegen/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /dgs-codegen/src/main/java/com/example/demo/gql/CustomCodeRegistry.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql; 2 | 3 | import com.netflix.graphql.dgs.DgsCodeRegistry; 4 | import com.netflix.graphql.dgs.DgsComponent; 5 | import graphql.schema.DataFetcher; 6 | import graphql.schema.FieldCoordinates; 7 | import graphql.schema.GraphQLCodeRegistry; 8 | import graphql.schema.idl.TypeDefinitionRegistry; 9 | 10 | import java.time.LocalDateTime; 11 | 12 | @DgsComponent 13 | public class CustomCodeRegistry { 14 | 15 | @DgsCodeRegistry 16 | public GraphQLCodeRegistry.Builder extraCodeRegistry(GraphQLCodeRegistry.Builder codeRegistryBuilder, TypeDefinitionRegistry registry) { 17 | 18 | DataFetcher df = (dfe) -> "Current timestamp is " + LocalDateTime.now(); 19 | FieldCoordinates coordinates = FieldCoordinates.coordinates("Query", "currentTimestamp"); 20 | 21 | return codeRegistryBuilder.dataFetcher(coordinates, df); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dgs-codegen/src/main/java/com/example/demo/gql/dataloaders/AuthorsDataLoader.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.dataloaders; 2 | 3 | import com.example.demo.gql.types.Author; 4 | import com.example.demo.service.AuthorService; 5 | import com.netflix.graphql.dgs.DgsDataLoader; 6 | import lombok.RequiredArgsConstructor; 7 | import org.dataloader.BatchLoader; 8 | 9 | import java.util.List; 10 | import java.util.concurrent.CompletableFuture; 11 | import java.util.concurrent.CompletionStage; 12 | 13 | @RequiredArgsConstructor 14 | @DgsDataLoader(name = "authorsLoader") 15 | public class AuthorsDataLoader implements BatchLoader { 16 | final AuthorService authorService; 17 | 18 | @Override 19 | public CompletionStage> load(List keys) { 20 | return CompletableFuture.supplyAsync(() -> 21 | this.authorService.getAuthorByIdIn(keys) 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dgs-codegen/src/main/java/com/example/demo/model/AuthorEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record AuthorEntity( 7 | UUID id, 8 | String name, 9 | String email, 10 | LocalDateTime createdAt 11 | ) { 12 | } 13 | 14 | -------------------------------------------------------------------------------- /dgs-codegen/src/main/java/com/example/demo/model/CommentEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record CommentEntity( 7 | UUID id, 8 | String content, 9 | LocalDateTime createdAt, 10 | UUID postId 11 | ) { 12 | } 13 | -------------------------------------------------------------------------------- /dgs-codegen/src/main/java/com/example/demo/model/PostEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record PostEntity( 7 | UUID id, 8 | String title, 9 | String content, 10 | String status, 11 | LocalDateTime createdAt, 12 | UUID authorId 13 | ) { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /dgs-codegen/src/main/java/com/example/demo/service/AuthorNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class AuthorNotFoundException extends RuntimeException { 4 | public AuthorNotFoundException(String id) { 5 | super("Author: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /dgs-codegen/src/main/java/com/example/demo/service/PostNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class PostNotFoundException extends RuntimeException { 4 | public PostNotFoundException(String id) { 5 | super("Post: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /dgs-codegen/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:postgresql://localhost/blogdb 2 | spring.datasource.username=user 3 | spring.datasource.password=password 4 | spring.sql.init.mode=always 5 | # 6 | # Logging level 7 | # 8 | logging.level.com.example=DEBUG 9 | logging.level.org.springframework.jdbc=DEBUG 10 | logging.level.web=DEBUG 11 | -------------------------------------------------------------------------------- /dgs-fileupload/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /dgs-fileupload/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/dgs-fileupload/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /dgs-fileupload/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /dgs-fileupload/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://repo.spring.io/milestone' } 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = 'dgs-fileupload' 9 | -------------------------------------------------------------------------------- /dgs-fileupload/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /dgs-fileupload/src/main/java/com/example/demo/gql/FileUploadInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import org.springframework.web.multipart.MultipartFile; 8 | 9 | @Data 10 | @Builder 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | public class FileUploadInput { 14 | private String description; 15 | private MultipartFile file; 16 | } 17 | -------------------------------------------------------------------------------- /dgs-fileupload/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Logging level 3 | # 4 | logging.level.com.example=DEBUG 5 | logging.level.web=DEBUG 6 | -------------------------------------------------------------------------------- /dgs-fileupload/src/main/resources/schema/schema.graphql: -------------------------------------------------------------------------------- 1 | scalar Upload 2 | 3 | type Mutation { 4 | upload(file: Upload!): Boolean 5 | uploadWithDesc(desc: String, file: Upload!): Boolean 6 | uploads(files: [Upload!]!): Boolean 7 | 8 | # the following def does not work. 9 | fileUpload(file: FileUploadInput!): Boolean 10 | fileUploads(files: [FileUploadInput!]!): Boolean 11 | } 12 | 13 | input FileUploadInput{ 14 | description: String 15 | file: Upload! 16 | } -------------------------------------------------------------------------------- /dgs-kotlin-co/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /dgs-kotlin-co/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/dgs-kotlin-co/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /dgs-kotlin-co/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /dgs-kotlin-co/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url = uri("https://repo.spring.io/milestone") } 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = "dgs-kotlin-co" 9 | -------------------------------------------------------------------------------- /dgs-kotlin-co/src/main/kotlin/com/example/demo/Extensions.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo 2 | 3 | import com.example.demo.gql.types.Author 4 | import com.example.demo.gql.types.Comment 5 | import com.example.demo.gql.types.Post 6 | import com.example.demo.model.AuthorEntity 7 | import com.example.demo.model.CommentEntity 8 | import com.example.demo.model.PostEntity 9 | 10 | fun PostEntity.asGqlType(): Post = Post( 11 | id = this.id!!, 12 | title = this.title, 13 | content = this.content, 14 | createdAt = this.createdAt, 15 | authorId = this.authorId 16 | ) 17 | 18 | fun CommentEntity.asGqlType(): Comment = Comment( 19 | id = this.id!!, 20 | content = this.content, 21 | createdAt = this.createdAt, 22 | postId = this.postId!! 23 | ) 24 | 25 | fun AuthorEntity.asGqlType(): Author = Author( 26 | id = this.id!!, 27 | name = this.name, 28 | email = this.email, 29 | createdAt = this.createdAt 30 | ) -------------------------------------------------------------------------------- /dgs-kotlin-co/src/main/kotlin/com/example/demo/gql/datafetcher/AuthorsDataFetcher.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.datafetcher 2 | 3 | import com.example.demo.gql.DgsConstants 4 | import com.example.demo.gql.types.Author 5 | import com.example.demo.gql.types.Post 6 | import com.example.demo.service.AuthorService 7 | import com.example.demo.service.PostService 8 | import com.netflix.graphql.dgs.* 9 | import kotlinx.coroutines.flow.toList 10 | import java.util.UUID 11 | 12 | @DgsComponent 13 | class AuthorsDataFetcher( 14 | val postService: PostService, 15 | val authorService: AuthorService 16 | ) { 17 | 18 | @DgsQuery 19 | suspend fun author(@InputArgument authorId: UUID) = authorService.getAuthorById(authorId) 20 | 21 | @DgsData(parentType = DgsConstants.AUTHOR.TYPE_NAME, field = DgsConstants.AUTHOR.Posts) 22 | suspend fun posts(dfe: DgsDataFetchingEnvironment): List { 23 | val a: Author = dfe.getSource()!! 24 | return postService.getPostsByAuthorId(a.id).toList() 25 | } 26 | } -------------------------------------------------------------------------------- /dgs-kotlin-co/src/main/kotlin/com/example/demo/gql/dataloader/AuthorsDataLoader.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.dataloader 2 | 3 | import com.example.demo.gql.types.Author 4 | import com.example.demo.service.AuthorService 5 | import com.netflix.graphql.dgs.DgsDataLoader 6 | import kotlinx.coroutines.CoroutineScope 7 | import kotlinx.coroutines.asCoroutineDispatcher 8 | import kotlinx.coroutines.flow.toList 9 | import kotlinx.coroutines.future.future 10 | import org.dataloader.BatchLoader 11 | import java.util.UUID 12 | import java.util.concurrent.CompletionStage 13 | import java.util.concurrent.Executors 14 | 15 | @DgsDataLoader(name = "authorsLoader") 16 | class AuthorsDataLoader(val authorService: AuthorService) : BatchLoader { 17 | val loaderScope = CoroutineScope(Executors.newCachedThreadPool().asCoroutineDispatcher()) 18 | override fun load(keys: List): CompletionStage> = loaderScope.future { 19 | authorService.getAuthorByIdIn(keys).toList() 20 | } 21 | } -------------------------------------------------------------------------------- /dgs-kotlin-co/src/main/kotlin/com/example/demo/model/AuthorEntity.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.model 2 | 3 | import org.springframework.data.annotation.CreatedDate 4 | import org.springframework.data.annotation.Id 5 | import org.springframework.data.relational.core.mapping.Column 6 | import org.springframework.data.relational.core.mapping.Table 7 | import java.time.LocalDateTime 8 | import java.util.* 9 | 10 | @Table(value = "users") 11 | data class AuthorEntity( 12 | @Id 13 | @Column("id") 14 | var id: UUID? = null, 15 | 16 | @Column("name") 17 | var name: String, 18 | 19 | @Column("email") 20 | var email: String, 21 | 22 | @Column("created_at") 23 | @CreatedDate 24 | var createdAt: LocalDateTime? = null, 25 | ) -------------------------------------------------------------------------------- /dgs-kotlin-co/src/main/kotlin/com/example/demo/model/CommentEntity.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.model 2 | 3 | import org.springframework.data.annotation.CreatedDate 4 | import org.springframework.data.annotation.Id 5 | import org.springframework.data.relational.core.mapping.Column 6 | import org.springframework.data.relational.core.mapping.Table 7 | import java.time.LocalDateTime 8 | import java.util.* 9 | 10 | @Table(value = "comments") 11 | data class CommentEntity( 12 | @Id 13 | @Column("id") 14 | var id: UUID? = null, 15 | 16 | @Column("content") 17 | var content: String, 18 | 19 | @Column("post_id") 20 | var postId: UUID? = null, 21 | 22 | @Column("created_at") 23 | @CreatedDate 24 | var createdAt: LocalDateTime? = null 25 | ) -------------------------------------------------------------------------------- /dgs-kotlin-co/src/main/kotlin/com/example/demo/model/PostStatus.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.model 2 | 3 | enum class PostStatus { 4 | DRAFT, PENDING_MODERATION, PUBLISHED 5 | } -------------------------------------------------------------------------------- /dgs-kotlin-co/src/main/kotlin/com/example/demo/repository/AuthorRepository.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.repository 2 | 3 | import com.example.demo.model.AuthorEntity 4 | import org.springframework.data.repository.kotlin.CoroutineCrudRepository 5 | import org.springframework.data.repository.kotlin.CoroutineSortingRepository 6 | import java.util.* 7 | 8 | interface AuthorRepository : CoroutineSortingRepository, 9 | CoroutineCrudRepository { 10 | suspend fun findByNameOrEmail(name: String, email: String): AuthorEntity 11 | } -------------------------------------------------------------------------------- /dgs-kotlin-co/src/main/kotlin/com/example/demo/repository/CommentRepository.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.repository 2 | 3 | import com.example.demo.model.CommentEntity 4 | import kotlinx.coroutines.flow.Flow 5 | import org.springframework.data.repository.kotlin.CoroutineCrudRepository 6 | import org.springframework.data.repository.kotlin.CoroutineSortingRepository 7 | import java.util.* 8 | 9 | interface CommentRepository : CoroutineSortingRepository, 10 | CoroutineCrudRepository { 11 | fun findByPostId(id: UUID): Flow 12 | fun findByPostIdIn(uuids: List): Flow 13 | } -------------------------------------------------------------------------------- /dgs-kotlin-co/src/main/kotlin/com/example/demo/repository/PostRepository.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.repository 2 | 3 | import com.example.demo.model.PostEntity 4 | import kotlinx.coroutines.flow.Flow 5 | import org.springframework.data.repository.kotlin.CoroutineCrudRepository 6 | import org.springframework.data.repository.kotlin.CoroutineSortingRepository 7 | import java.util.* 8 | 9 | interface PostRepository : CoroutineSortingRepository , 10 | CoroutineCrudRepository{ 11 | fun findByAuthorId(id: UUID): Flow 12 | } -------------------------------------------------------------------------------- /dgs-kotlin-co/src/main/kotlin/com/example/demo/service/AuthorNotFoundException.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.service 2 | 3 | import java.util.* 4 | 5 | class AuthorNotFoundException(id: UUID) : RuntimeException("Author: $id was not found.") 6 | 7 | -------------------------------------------------------------------------------- /dgs-kotlin-co/src/main/kotlin/com/example/demo/service/AuthorService.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.service 2 | 3 | import com.example.demo.asGqlType 4 | import com.example.demo.gql.types.Author 5 | import com.example.demo.repository.AuthorRepository 6 | import kotlinx.coroutines.flow.Flow 7 | import kotlinx.coroutines.flow.map 8 | import org.springframework.stereotype.Service 9 | import java.util.* 10 | 11 | @Service 12 | class AuthorService(val authors: AuthorRepository) { 13 | 14 | suspend fun getAuthorById(id: UUID): Author { 15 | val author = this.authors.findById(id) ?: throw AuthorNotFoundException(id) 16 | return author.asGqlType() 17 | } 18 | 19 | // alternative to use kotlin co `Flow` 20 | fun getAuthorByIdIn(ids: List): Flow { 21 | return authors.findAllById(ids).map { it.asGqlType() } 22 | } 23 | } -------------------------------------------------------------------------------- /dgs-kotlin-co/src/main/kotlin/com/example/demo/service/PostNotFoundException.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.service 2 | 3 | import java.util.UUID 4 | 5 | class PostNotFoundException(id: UUID) : RuntimeException("Post: $id was not found.") -------------------------------------------------------------------------------- /dgs-kotlin-co/src/main/kotlin/com/example/demo/service/PostService.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.service 2 | 3 | import com.example.demo.gql.types.Comment 4 | import com.example.demo.gql.types.CommentInput 5 | import com.example.demo.gql.types.CreatePostInput 6 | import com.example.demo.gql.types.Post 7 | import kotlinx.coroutines.flow.Flow 8 | import reactor.core.publisher.Flux 9 | import java.util.UUID 10 | 11 | interface PostService { 12 | fun allPosts(): Flow 13 | 14 | suspend fun getPostById(id: UUID): Post 15 | fun getPostsByAuthorId(id: UUID): Flow 16 | 17 | suspend fun createPost(postInput: CreatePostInput): Post 18 | 19 | suspend fun addComment(commentInput: CommentInput): Comment 20 | 21 | // subscription: commentAdded 22 | fun commentAdded(): Flow 23 | fun getCommentsByPostId(id: UUID): Flow 24 | fun getCommentsByPostIdIn(ids: List): Flow 25 | } -------------------------------------------------------------------------------- /dgs-kotlin-co/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #dgs.graphql.schema-locations[0]= 2 | logging.level.root=INFO 3 | logging.level.web=DEBUG 4 | logging.level.sql=DEBUG 5 | logging.level.com.example=DEBUG 6 | logging.level.org.springframework.graphql=TRACE 7 | logging.level.org.springframework.security=DEBUG 8 | logging.level.reactor.core.publisher=TRACE 9 | 10 | # r2dbc 11 | spring.r2dbc.url=r2dbc:postgresql://localhost/blogdb 12 | spring.r2dbc.username=user 13 | spring.r2dbc.password=password 14 | spring.sql.init.mode=always 15 | 16 | # security 17 | spring.security.user.name=user 18 | spring.security.user.password=password 19 | spring.security.user.roles=USER 20 | 21 | # graphql 22 | spring.graphql.websocket.path=/graphql -------------------------------------------------------------------------------- /dgs-kotlin/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /dgs-kotlin/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/dgs-kotlin/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /dgs-kotlin/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /dgs-kotlin/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url = uri("https://repo.spring.io/milestone") } 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = "dgs-kotlin" 9 | -------------------------------------------------------------------------------- /dgs-kotlin/src/main/kotlin/com/example/demo/gql/dataloaders/AuthorsDataLoader.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.dataloaders 2 | 3 | import com.example.demo.gql.types.Author 4 | import com.example.demo.service.AuthorService 5 | import com.netflix.graphql.dgs.DgsDataLoader 6 | import org.dataloader.BatchLoader 7 | import java.util.UUID 8 | import java.util.concurrent.CompletableFuture.completedFuture 9 | import java.util.concurrent.CompletableFuture.supplyAsync 10 | import java.util.concurrent.CompletionStage 11 | 12 | @DgsDataLoader(name = "authorsLoader") 13 | class AuthorsDataLoader(val authorService: AuthorService) : BatchLoader { 14 | override fun load(keys: List): CompletionStage> = completedFuture( 15 | authorService.getAuthorByIdIn(keys) 16 | ) 17 | } 18 | 19 | -------------------------------------------------------------------------------- /dgs-kotlin/src/main/kotlin/com/example/demo/model/AuthorEntity.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.model 2 | 3 | import org.springframework.data.annotation.CreatedDate 4 | import org.springframework.data.annotation.Id 5 | import org.springframework.data.relational.core.mapping.Column 6 | import org.springframework.data.relational.core.mapping.Table 7 | import java.time.LocalDateTime 8 | import java.util.* 9 | 10 | @Table(value = "users") 11 | data class AuthorEntity( 12 | @Id 13 | @Column("id") 14 | var id: UUID? = null, 15 | 16 | @Column("name") 17 | var name: String, 18 | 19 | @Column("password") 20 | var password: String, 21 | 22 | @Column("email") 23 | var email: String, 24 | 25 | @Column("created_at") 26 | @CreatedDate 27 | var createdAt: LocalDateTime? = null, 28 | ) -------------------------------------------------------------------------------- /dgs-kotlin/src/main/kotlin/com/example/demo/model/CommentEntity.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.model 2 | 3 | import org.springframework.data.annotation.CreatedDate 4 | import org.springframework.data.annotation.Id 5 | import org.springframework.data.relational.core.mapping.Column 6 | import org.springframework.data.relational.core.mapping.Table 7 | import java.time.LocalDateTime 8 | import java.util.* 9 | 10 | @Table(value = "comments") 11 | data class CommentEntity( 12 | @Id 13 | @Column("id") 14 | var id: UUID? = null, 15 | 16 | @Column("content") 17 | var content: String, 18 | 19 | @Column("post_id") 20 | var postId: UUID? = null, 21 | 22 | @Column("created_at") 23 | @CreatedDate 24 | var createdAt: LocalDateTime? = null 25 | ) -------------------------------------------------------------------------------- /dgs-kotlin/src/main/kotlin/com/example/demo/model/PostEntity.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.model 2 | 3 | import org.springframework.data.annotation.* 4 | import org.springframework.data.relational.core.mapping.Column 5 | import org.springframework.data.relational.core.mapping.Table 6 | import java.time.LocalDateTime 7 | import java.util.* 8 | 9 | @Table(value = "posts") 10 | data class PostEntity( 11 | @Id 12 | @Column("id") 13 | var id: UUID? = null, 14 | 15 | @Column("title") 16 | var title: String, 17 | 18 | @Column("content") 19 | var content: String? = null, 20 | 21 | @Column("status") 22 | var status: PostStatus = PostStatus.DRAFT, 23 | 24 | @CreatedBy 25 | @Column("author_id") 26 | var authorId: UUID? = null, 27 | 28 | @Column("created_at") 29 | @CreatedDate 30 | var createdAt: LocalDateTime? = null, 31 | 32 | @Column("updated_at") 33 | @LastModifiedDate 34 | var updatedAt: LocalDateTime? = null, 35 | 36 | @Column("version") 37 | @Version 38 | var version: Long? = null 39 | ) -------------------------------------------------------------------------------- /dgs-kotlin/src/main/kotlin/com/example/demo/model/PostStatus.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.model 2 | 3 | enum class PostStatus { 4 | DRAFT, PENDING_MODERATION, PUBLISHED 5 | } -------------------------------------------------------------------------------- /dgs-kotlin/src/main/kotlin/com/example/demo/model/ProfileEntity.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.model 2 | 3 | import org.springframework.data.annotation.CreatedBy 4 | import org.springframework.data.annotation.CreatedDate 5 | import org.springframework.data.annotation.Id 6 | import org.springframework.data.relational.core.mapping.Column 7 | import org.springframework.data.relational.core.mapping.Table 8 | import java.time.LocalDateTime 9 | import java.util.* 10 | 11 | @Table(value = "profiles") 12 | data class ProfileEntity( 13 | @Id 14 | @Column("id") 15 | var id: UUID? = null, 16 | 17 | @Column("cover_img_id") 18 | var coverImgId: String, 19 | 20 | @Column("bio") 21 | var bio: String? = null, 22 | 23 | @CreatedBy 24 | @Column("user_id") 25 | var userId: UUID? = null, 26 | 27 | @Column("created_at") 28 | @CreatedDate 29 | var createdAt: LocalDateTime? = null, 30 | ) -------------------------------------------------------------------------------- /dgs-kotlin/src/main/kotlin/com/example/demo/repository/AuthorRepository.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.repository 2 | 3 | import com.example.demo.model.AuthorEntity 4 | import org.springframework.data.repository.CrudRepository 5 | import org.springframework.data.repository.PagingAndSortingRepository 6 | import java.util.* 7 | 8 | interface AuthorRepository : CrudRepository, 9 | PagingAndSortingRepository { 10 | fun findByNameOrEmail(name: String, email: String): AuthorEntity? 11 | } -------------------------------------------------------------------------------- /dgs-kotlin/src/main/kotlin/com/example/demo/repository/CommentRepository.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.repository 2 | 3 | import com.example.demo.model.CommentEntity 4 | import org.springframework.data.repository.CrudRepository 5 | import org.springframework.data.repository.PagingAndSortingRepository 6 | import java.util.* 7 | 8 | interface CommentRepository : CrudRepository, 9 | PagingAndSortingRepository { 10 | fun findByPostId(id: UUID): List 11 | fun findByPostIdIn(uuids: List): List 12 | } -------------------------------------------------------------------------------- /dgs-kotlin/src/main/kotlin/com/example/demo/repository/PostRepository.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.repository 2 | 3 | import com.example.demo.model.PostEntity 4 | import org.springframework.data.repository.CrudRepository 5 | import org.springframework.data.repository.PagingAndSortingRepository 6 | import java.util.* 7 | 8 | interface PostRepository : CrudRepository, 9 | PagingAndSortingRepository { 10 | fun findByAuthorId(id: UUID): List 11 | } -------------------------------------------------------------------------------- /dgs-kotlin/src/main/kotlin/com/example/demo/repository/ProfileRepository.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.repository 2 | 3 | import com.example.demo.model.ProfileEntity 4 | import org.springframework.data.repository.CrudRepository 5 | import org.springframework.data.repository.PagingAndSortingRepository 6 | import java.util.* 7 | 8 | interface ProfileRepository : CrudRepository, 9 | PagingAndSortingRepository { 10 | fun findByUserId(id: UUID): ProfileEntity? 11 | } -------------------------------------------------------------------------------- /dgs-kotlin/src/main/kotlin/com/example/demo/service/AuthorNotFoundException.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.service 2 | 3 | import java.util.UUID 4 | 5 | class AuthorNotFoundException(id: UUID) : RuntimeException("Author: $id was not found.") -------------------------------------------------------------------------------- /dgs-kotlin/src/main/kotlin/com/example/demo/service/PostNotFoundException.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.service 2 | 3 | import java.util.UUID 4 | 5 | class PostNotFoundException(id: UUID) : RuntimeException("Post: $id was not found.") 6 | 7 | -------------------------------------------------------------------------------- /dgs-kotlin/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:postgresql://localhost/blogdb 2 | spring.datasource.username=user 3 | spring.datasource.password=password 4 | spring.sql.init.mode=always 5 | # 6 | # Logging level 7 | # 8 | logging.level.web=DEBUG 9 | logging.level.sql=DEBUG 10 | logging.level.root=INFO 11 | logging.level.com.example=DEBUG 12 | logging.level.org.springframework.web.socket=DEBUG 13 | logging.level.com.netflix.graphql.dgs=DEBUG 14 | 15 | dgs.graphql.websocket.path=/subscriptions 16 | dgs.graphql.websocket.subscription-error-log-level=DEBUG 17 | -------------------------------------------------------------------------------- /dgs-kotlin/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | DELETE FROM posts; 2 | DELETE FROM profiles; 3 | DELETE FROM users; 4 | -------------------------------------------------------------------------------- /dgs-kotlin/src/test/kotlin/com/example/demo/TestConfigInitializer.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo 2 | 3 | import org.springframework.context.ApplicationContextInitializer 4 | import org.springframework.context.support.GenericApplicationContext 5 | 6 | class TestConfigInitializer: ApplicationContextInitializer{ 7 | override fun initialize(applicationContext: GenericApplicationContext) { 8 | beans.initialize(applicationContext) 9 | } 10 | } -------------------------------------------------------------------------------- /dgs-subscription-sse/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /dgs-subscription-sse/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/dgs-subscription-sse/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /dgs-subscription-sse/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /dgs-subscription-sse/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url = uri("https://repo.spring.io/milestone") } 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = "dgs-subscription-sse" 9 | -------------------------------------------------------------------------------- /dgs-subscription-sse/src/main/kotlin/com/example/demo/DemoApplication.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class DemoApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /dgs-subscription-sse/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #dgs.graphql.schema-locations[0]= 2 | logging.level.com.example=DEBUG 3 | logging.level.web=DEBUG 4 | logging.level.com.netflix.graphql.dgs=TRACE 5 | 6 | spring.mvc.async.request-timeout=45000 -------------------------------------------------------------------------------- /dgs-subscription-sse/src/main/resources/schema/schema.graphql: -------------------------------------------------------------------------------- 1 | type TextMessage { 2 | id: ID! 3 | body: String! 4 | sentAt: LocalDateTime 5 | } 6 | 7 | type Query { 8 | messages:[TextMessage!]! 9 | } 10 | 11 | type Mutation { 12 | send(message:TextMessageInput!): TextMessage 13 | } 14 | 15 | input TextMessageInput { 16 | body: String! 17 | } 18 | 19 | type Subscription { 20 | messageSent: TextMessage! 21 | } 22 | 23 | scalar LocalDateTime 24 | -------------------------------------------------------------------------------- /dgs-subscription-ui/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /dgs-subscription-ui/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | 16 | # IDEs and editors 17 | /.idea 18 | .project 19 | .classpath 20 | .c9/ 21 | *.launch 22 | .settings/ 23 | *.sublime-workspace 24 | 25 | # IDE - VSCode 26 | .vscode/* 27 | !.vscode/settings.json 28 | !.vscode/tasks.json 29 | !.vscode/launch.json 30 | !.vscode/extensions.json 31 | .history/* 32 | 33 | # misc 34 | /.angular/cache 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /dgs-subscription-ui/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | .container { 2 | font-size: 14px; 3 | display: flex; 4 | flex-flow: column nowrap; 5 | justify-content: space-around; 6 | height: 100%; 7 | 8 | } 9 | 10 | .messages{ 11 | display: flex; 12 | flex-basis: auto; 13 | flex-grow: 4; 14 | margin: 5rem 2rem; 15 | } 16 | 17 | .messageBox{ 18 | display: flex; 19 | flex-flow: row nowrap; 20 | justify-content: space-between; 21 | margin: 5rem 2rem; 22 | } 23 | 24 | .messageField{ 25 | flex-grow: 4; 26 | flex-flow: column nowrap; 27 | } 28 | -------------------------------------------------------------------------------- /dgs-subscription-ui/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 | {{ m | json }} 5 |

6 |
7 | 8 |
9 | 10 | 17 | 18 | Message body can not be empty. 19 | 20 | 21 |
22 | 29 |
30 |
31 |
32 | -------------------------------------------------------------------------------- /dgs-subscription-ui/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/dgs-subscription-ui/src/assets/.gitkeep -------------------------------------------------------------------------------- /dgs-subscription-ui/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /dgs-subscription-ui/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /dgs-subscription-ui/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/dgs-subscription-ui/src/favicon.ico -------------------------------------------------------------------------------- /dgs-subscription-ui/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DgsSubscriptionUi 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /dgs-subscription-ui/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /dgs-subscription-ui/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | html, body { height: 100%; } 4 | body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } 5 | -------------------------------------------------------------------------------- /dgs-subscription-ui/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | // First, initialize the Angular testing environment. 11 | getTestBed().initTestEnvironment( 12 | BrowserDynamicTestingModule, 13 | platformBrowserDynamicTesting(), { 14 | teardown: { destroyAfterEach: false } 15 | } 16 | ); 17 | -------------------------------------------------------------------------------- /dgs-subscription-ui/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /dgs-subscription-ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "sourceMap": true, 12 | "declaration": false, 13 | "experimentalDecorators": true, 14 | "moduleResolution": "node", 15 | "importHelpers": true, 16 | "target": "ES2022", 17 | "module": "es2020", 18 | "lib": [ 19 | "es2020", 20 | "dom" 21 | ], 22 | "useDefineForClassFields": false 23 | }, 24 | "angularCompilerOptions": { 25 | "enableI18nLegacyMessageIdFormat": false, 26 | "strictInjectionParameters": true, 27 | "strictInputAccessModifiers": true, 28 | "strictTemplates": true 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dgs-subscription-ui/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /dgs-subscription-ws/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /dgs-subscription-ws/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/dgs-subscription-ws/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /dgs-subscription-ws/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /dgs-subscription-ws/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url = uri("https://repo.spring.io/milestone") } 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = "demo" 9 | -------------------------------------------------------------------------------- /dgs-subscription-ws/src/main/kotlin/com/example/demo/DemoApplication.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | import org.springframework.context.annotation.Configuration 6 | import org.springframework.web.servlet.config.annotation.CorsRegistry 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer 8 | 9 | @SpringBootApplication 10 | class DemoApplication 11 | 12 | fun main(args: Array) { 13 | runApplication(*args) 14 | } 15 | 16 | @Configuration 17 | class WebConfig : WebMvcConfigurer { 18 | override fun addCorsMappings(registry: CorsRegistry) { 19 | registry.addMapping("/**") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /dgs-subscription-ws/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #dgs.graphql.schema-locations[0]= 2 | logging.level.com.example=DEBUG 3 | logging.level.web=DEBUG 4 | logging.level.reactor.core.publisher=TRACE 5 | 6 | spring.graphql.websocket.path=/graphql 7 | spring.graphql.websocket.connection-init-timeout=30s 8 | spring.graphql.websocket.keep-alive=60s 9 | -------------------------------------------------------------------------------- /dgs-subscription-ws/src/main/resources/schema/schema.graphql: -------------------------------------------------------------------------------- 1 | type TextMessage { 2 | id: ID! 3 | body: String! 4 | sentAt: LocalDateTime 5 | } 6 | 7 | type Query { 8 | messages:[TextMessage!]! 9 | } 10 | 11 | type Mutation { 12 | send(message:TextMessageInput!): TextMessage 13 | } 14 | 15 | input TextMessageInput { 16 | body: String! 17 | } 18 | 19 | type Subscription { 20 | messageSent: TextMessage! 21 | } 22 | 23 | scalar LocalDateTime 24 | -------------------------------------------------------------------------------- /dgs-webflux/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /dgs-webflux/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/dgs-webflux/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /dgs-webflux/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /dgs-webflux/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://repo.spring.io/milestone' } 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = 'dgs-webflux' 9 | -------------------------------------------------------------------------------- /dgs-webflux/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /dgs-webflux/src/main/java/com/example/demo/gql/dataloaders/AuthorsDataLoader.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.dataloaders; 2 | 3 | import com.example.demo.gql.types.Author; 4 | import com.example.demo.service.AuthorService; 5 | import com.netflix.graphql.dgs.DgsDataLoader; 6 | import lombok.RequiredArgsConstructor; 7 | import org.dataloader.BatchLoader; 8 | 9 | import java.util.List; 10 | import java.util.concurrent.CompletionStage; 11 | 12 | @RequiredArgsConstructor 13 | @DgsDataLoader(name = "authorsLoader") 14 | public class AuthorsDataLoader implements BatchLoader { 15 | final AuthorService authorService; 16 | 17 | @Override 18 | public CompletionStage> load(List keys) { 19 | return this.authorService.getAuthorByIdIn(keys).collectList().toFuture(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /dgs-webflux/src/main/java/com/example/demo/gql/types/Author.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | import lombok.ToString; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | @Data 11 | @Builder 12 | @ToString 13 | public class Author { 14 | Long id; 15 | String name; 16 | String email; 17 | @Builder.Default 18 | List posts = new ArrayList<>(); 19 | } 20 | -------------------------------------------------------------------------------- /dgs-webflux/src/main/java/com/example/demo/gql/types/Comment.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.*; 4 | 5 | @Data 6 | @Builder 7 | @ToString 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class Comment { 11 | Long id; 12 | Long postId; 13 | String content; 14 | } 15 | -------------------------------------------------------------------------------- /dgs-webflux/src/main/java/com/example/demo/gql/types/CommentInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.*; 4 | import org.hibernate.validator.constraints.Length; 5 | 6 | import jakarta.validation.constraints.NotEmpty; 7 | 8 | @Getter 9 | @Setter 10 | @ToString 11 | @Builder 12 | @AllArgsConstructor 13 | @RequiredArgsConstructor 14 | public class CommentInput { 15 | @NotEmpty 16 | @Length(min = 5, max = 50) 17 | String content; 18 | 19 | @NotEmpty 20 | String postId; 21 | } 22 | -------------------------------------------------------------------------------- /dgs-webflux/src/main/java/com/example/demo/gql/types/CreatePostInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.*; 4 | import org.hibernate.validator.constraints.Length; 5 | 6 | import jakarta.validation.constraints.NotEmpty; 7 | 8 | @Getter 9 | @Setter 10 | @ToString 11 | @RequiredArgsConstructor 12 | public class CreatePostInput { 13 | @NotEmpty 14 | @Length(min = 5, max = 100) 15 | String title; 16 | 17 | @NotEmpty 18 | @Length(min = 5, max = 1000) 19 | String content; 20 | } 21 | -------------------------------------------------------------------------------- /dgs-webflux/src/main/java/com/example/demo/gql/types/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.*; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | @Data 9 | @Builder 10 | @ToString 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | public class Post { 14 | Long id; 15 | String title; 16 | String content; 17 | 18 | @Builder.Default 19 | List comments = new ArrayList<>(); 20 | Long authorId; 21 | Author author; 22 | } 23 | -------------------------------------------------------------------------------- /dgs-webflux/src/main/java/com/example/demo/model/AuthorEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record AuthorEntity( 7 | Long id, 8 | String name, 9 | String email 10 | ) { 11 | } 12 | 13 | -------------------------------------------------------------------------------- /dgs-webflux/src/main/java/com/example/demo/model/CommentEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record CommentEntity( 7 | Long id, 8 | String content, 9 | Long postId 10 | ) { 11 | } 12 | -------------------------------------------------------------------------------- /dgs-webflux/src/main/java/com/example/demo/model/PostEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record PostEntity( 7 | Long id, 8 | String title, 9 | String content, 10 | String status, 11 | Long authorId 12 | ) { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /dgs-webflux/src/main/java/com/example/demo/service/AuthorNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class AuthorNotFoundException extends RuntimeException { 4 | public AuthorNotFoundException(Long id) { 5 | super("Author: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /dgs-webflux/src/main/java/com/example/demo/service/PostNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class PostNotFoundException extends RuntimeException { 4 | public PostNotFoundException(Long id) { 5 | super("Post: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /dgs-webflux/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.r2dbc.url=r2dbc:postgresql://localhost/blogdb 2 | spring.r2dbc.username=user 3 | spring.r2dbc.password=password 4 | spring.sql.init.mode=always 5 | 6 | logging.level.root=INFO 7 | logging.level.sql=DEBUG 8 | logging.level.web=DEBUG 9 | logging.level.com.example=DEBUG 10 | logging.level.org.springframework.graphql=TRACE 11 | 12 | spring.graphql.websocket.path=/graphql 13 | -------------------------------------------------------------------------------- /dgs-webflux/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS users 2 | ( 3 | id BIGSERIAL PRIMARY KEY, 4 | name VARCHAR(255) NOT NULL, 5 | email VARCHAR(255) NOT NULL 6 | ); 7 | 8 | CREATE TABLE IF NOT EXISTS posts 9 | ( 10 | id BIGSERIAL PRIMARY KEY, 11 | title VARCHAR(255), 12 | content VARCHAR(255), 13 | status VARCHAR(255) DEFAULT 'DRAFT', 14 | author_id BIGINT REFERENCES users(id) ON DELETE CASCADE 15 | ); 16 | 17 | CREATE TABLE IF NOT EXISTS comments 18 | ( 19 | id BIGSERIAL PRIMARY KEY, 20 | content VARCHAR(255), 21 | post_id BIGINT REFERENCES posts(id) ON DELETE CASCADE 22 | ); 23 | -------------------------------------------------------------------------------- /dgs-webflux/src/main/resources/schema/schema.graphql: -------------------------------------------------------------------------------- 1 | type Post{ 2 | id: ID! 3 | title: String! 4 | content: String 5 | comments: [Comment] 6 | authorId:ID 7 | author:Author 8 | } 9 | type Author{ 10 | id:ID! 11 | name:String! 12 | email:String! 13 | posts: [Post] 14 | } 15 | type Comment{ 16 | id: ID! 17 | content: String! 18 | postId: String! 19 | } 20 | 21 | input CreatePostInput { 22 | title: String! 23 | content: String! 24 | } 25 | 26 | input CommentInput{ 27 | postId: ID! 28 | content: String! 29 | } 30 | 31 | type Query{ 32 | allPosts: [Post!]! 33 | postById(postId: ID!): Post 34 | } 35 | 36 | type Mutation{ 37 | createPost(createPostInput: CreatePostInput!): Post! 38 | addComment(commentInput: CommentInput!): Comment! 39 | } 40 | 41 | type Subscription{ 42 | commentAdded: Comment! 43 | } -------------------------------------------------------------------------------- /dgs/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /dgs/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/dgs/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /dgs/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /dgs/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://repo.spring.io/milestone' } 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = 'dgs' 9 | -------------------------------------------------------------------------------- /dgs/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /dgs/src/main/java/com/example/demo/gql/dataloaders/AuthorsDataLoader.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.dataloaders; 2 | 3 | import com.example.demo.gql.types.Author; 4 | import com.example.demo.service.AuthorService; 5 | import com.netflix.graphql.dgs.DgsDataLoader; 6 | import lombok.RequiredArgsConstructor; 7 | import org.dataloader.BatchLoader; 8 | 9 | import java.util.List; 10 | import java.util.concurrent.CompletableFuture; 11 | import java.util.concurrent.CompletionStage; 12 | 13 | @RequiredArgsConstructor 14 | @DgsDataLoader(name = "authorsLoader") 15 | public class AuthorsDataLoader implements BatchLoader { 16 | final AuthorService authorService; 17 | 18 | @Override 19 | public CompletionStage> load(List keys) { 20 | return CompletableFuture.supplyAsync(() -> 21 | this.authorService.getAuthorByIdIn(keys) 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dgs/src/main/java/com/example/demo/gql/types/Author.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | import lombok.ToString; 6 | 7 | @Data 8 | @Builder 9 | @ToString 10 | public class Author { 11 | Long id; 12 | String name; 13 | String email; 14 | } 15 | -------------------------------------------------------------------------------- /dgs/src/main/java/com/example/demo/gql/types/Comment.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | import lombok.ToString; 6 | 7 | @Data 8 | @Builder 9 | @ToString 10 | public class Comment { 11 | Long id; 12 | Long postId; 13 | String content; 14 | } 15 | -------------------------------------------------------------------------------- /dgs/src/main/java/com/example/demo/gql/types/CommentInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.*; 4 | import org.hibernate.validator.constraints.Length; 5 | 6 | import jakarta.validation.constraints.NotEmpty; 7 | 8 | @Getter 9 | @Setter 10 | @ToString 11 | @RequiredArgsConstructor 12 | public class CommentInput { 13 | 14 | @NotEmpty 15 | @Length(min = 10, max = 50) 16 | String content; 17 | 18 | @NotEmpty 19 | String postId; 20 | } 21 | -------------------------------------------------------------------------------- /dgs/src/main/java/com/example/demo/gql/types/CreatePostInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.*; 4 | import org.hibernate.validator.constraints.Length; 5 | 6 | import jakarta.validation.constraints.NotEmpty; 7 | 8 | @Getter 9 | @Setter 10 | @ToString 11 | @RequiredArgsConstructor 12 | public class CreatePostInput { 13 | @NotEmpty 14 | @Length(min = 5, max = 100) 15 | String title; 16 | 17 | @NotEmpty 18 | String content; 19 | } 20 | -------------------------------------------------------------------------------- /dgs/src/main/java/com/example/demo/gql/types/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | import lombok.ToString; 6 | import lombok.extern.slf4j.Slf4j; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | @Data 12 | @Builder 13 | @ToString 14 | @Slf4j 15 | public class Post { 16 | Long id; 17 | String title; 18 | String content; 19 | @Builder.Default 20 | PostStatus status = PostStatus.DRAFT; 21 | @Builder.Default 22 | List comments = new ArrayList<>(); 23 | Long authorId; 24 | Author author; 25 | 26 | public void addComment(Comment comment) { 27 | comment.setPostId(this.id); 28 | this.comments.add(comment); 29 | log.info("post comments: {}", this.comments); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /dgs/src/main/java/com/example/demo/gql/types/PostStatus.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | public enum PostStatus { 4 | DRAFT, PUBLISHED; 5 | } 6 | -------------------------------------------------------------------------------- /dgs/src/main/java/com/example/demo/model/AuthorEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | public record AuthorEntity( 4 | Long id, 5 | String name, 6 | String email 7 | ) { 8 | } 9 | 10 | -------------------------------------------------------------------------------- /dgs/src/main/java/com/example/demo/model/CommentEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | public record CommentEntity( 4 | Long id, 5 | String content, 6 | Long postId 7 | ) { 8 | } 9 | -------------------------------------------------------------------------------- /dgs/src/main/java/com/example/demo/model/PostEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | public record PostEntity( 4 | Long id, 5 | String title, 6 | String content, 7 | String status, 8 | Long authorId 9 | ) { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /dgs/src/main/java/com/example/demo/service/AuthorNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class AuthorNotFoundException extends RuntimeException { 4 | public AuthorNotFoundException(Long id) { 5 | super("Author: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /dgs/src/main/java/com/example/demo/service/PostNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class PostNotFoundException extends RuntimeException { 4 | public PostNotFoundException(Long id) { 5 | super("Post: #" + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /dgs/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:postgresql://localhost/blogdb 2 | spring.datasource.username=user 3 | spring.datasource.password=password 4 | spring.sql.init.mode=always 5 | #dgs.graphql.schema-locations[0]= 6 | logging.level.com.example=DEBUG 7 | logging.level.web=DEBUG 8 | 9 | spring.mvc.async.request-timeout=45000 -------------------------------------------------------------------------------- /dgs/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS users 2 | ( 3 | id BIGSERIAL PRIMARY KEY, 4 | name VARCHAR(255) NOT NULL, 5 | email VARCHAR(255) NOT NULL 6 | ); 7 | 8 | CREATE TABLE IF NOT EXISTS posts 9 | ( 10 | id BIGSERIAL PRIMARY KEY, 11 | title VARCHAR(255), 12 | content VARCHAR(255), 13 | status VARCHAR(255) DEFAULT 'DRAFT', 14 | author_id BIGINT REFERENCES users(id) ON DELETE CASCADE 15 | ); 16 | 17 | CREATE TABLE IF NOT EXISTS comments 18 | ( 19 | id BIGSERIAL PRIMARY KEY, 20 | content VARCHAR(255), 21 | post_id BIGINT REFERENCES posts(id) ON DELETE CASCADE 22 | ); 23 | -------------------------------------------------------------------------------- /dgs/src/main/resources/schema/schema.graphql: -------------------------------------------------------------------------------- 1 | type Post{ 2 | id: ID! 3 | title: String! 4 | content: String 5 | comments: [Comment] 6 | authorId:String 7 | author:Author 8 | } 9 | type Author{ 10 | id:ID! 11 | name:String! 12 | email:String! 13 | posts: [Post] 14 | } 15 | type Comment{ 16 | id: ID! 17 | content: String! 18 | postId: String! 19 | } 20 | 21 | input CreatePostInput { 22 | title: String! 23 | content: String! 24 | } 25 | 26 | input CommentInput{ 27 | postId: String! 28 | content: String! 29 | } 30 | 31 | type Query{ 32 | allPosts: [Post!]! 33 | postById(postId: ID!): Post 34 | } 35 | 36 | type Mutation{ 37 | createPost(createPostInput: CreatePostInput!): Post! 38 | } 39 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Define the services/containers to be run 2 | services: 3 | postgres: 4 | image: postgres 5 | ports: 6 | - "5432:5432" 7 | restart: always 8 | environment: 9 | POSTGRES_PASSWORD: password 10 | POSTGRES_DB: blogdb 11 | POSTGRES_USER: user 12 | volumes: 13 | - ./data/postgresql:/var/lib/postgresql 14 | - ./pg-initdb.d:/docker-entrypoint-initdb.d 15 | 16 | redis: 17 | image: redis 18 | ports: 19 | - "6379:6379" 20 | 21 | mongodb: 22 | image: mongo 23 | ports: 24 | - "27017:27017" 25 | volumes: 26 | - ./data/mongodb:/data/db 27 | -------------------------------------------------------------------------------- /docs/sec.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ```bash 10 | 127.0.0.1:6379> keys * 11 | 1) "spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:user" 12 | 2) "spring:session:sessions:e3fdb05c-69d3-4eae-9882-5d85d5357ba8" 13 | 3) "spring:session:sessions:expires:e3fdb05c-69d3-4eae-9882-5d85d5357ba8" 14 | 4) "spring:session:expirations:1623741240000" 15 | ``` 16 | 17 | -------------------------------------------------------------------------------- /docs/ui-allPosts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/docs/ui-allPosts.png -------------------------------------------------------------------------------- /docs/ui-createPost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/docs/ui-createPost.png -------------------------------------------------------------------------------- /docs/ui-postById.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/docs/ui-postById.png -------------------------------------------------------------------------------- /graphql-kotlin/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /graphql-kotlin/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/graphql-kotlin/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /graphql-kotlin/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /graphql-kotlin/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url = uri("https://repo.spring.io/milestone") } 4 | gradlePluginPortal() 5 | } 6 | } 7 | rootProject.name = "demo" 8 | -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/Extensions.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo 2 | 3 | import com.example.demo.gql.types.Author 4 | import com.example.demo.gql.types.Comment 5 | import com.example.demo.gql.types.Post 6 | import com.example.demo.model.AuthorEntity 7 | import com.example.demo.model.CommentEntity 8 | import com.example.demo.model.PostEntity 9 | 10 | fun PostEntity.asGqlType(): Post = Post( 11 | id = this.id, 12 | title = this.title, 13 | content = this.content, 14 | status = this.status.name, 15 | createdAt = this.createdAt, 16 | authorId = this.authorId 17 | ) 18 | 19 | fun CommentEntity.asGqlType(): Comment = Comment( 20 | id = this.id, 21 | content = this.content, 22 | createdAt = this.createdAt, 23 | postId = this.postId 24 | ) 25 | 26 | fun AuthorEntity.asGqlType(): Author = Author( 27 | id = this.id, 28 | name = this.name, 29 | email = this.email, 30 | createdAt = this.createdAt 31 | ) -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/gql/CustomSchemaGeneratorHooks.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql 2 | 3 | import com.example.demo.gql.scalars.Scalars 4 | import com.expediagroup.graphql.generator.directives.KotlinDirectiveWiringFactory 5 | import com.expediagroup.graphql.generator.hooks.FlowSubscriptionSchemaGeneratorHooks 6 | import graphql.schema.GraphQLType 7 | import java.time.LocalDateTime 8 | import java.util.* 9 | import kotlin.reflect.KType 10 | 11 | class CustomSchemaGeneratorHooks(override val wiringFactory: KotlinDirectiveWiringFactory) : 12 | FlowSubscriptionSchemaGeneratorHooks() { 13 | override fun willGenerateGraphQLType(type: KType): GraphQLType? = when (type.classifier) { 14 | UUID::class -> Scalars.uuidType // use val instead of fun, else a duplication exception thrown. 15 | LocalDateTime::class -> Scalars.localDateTimeType 16 | else -> null 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/gql/datafetchers/Mutations.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.datafetchers 2 | 3 | import com.example.demo.service.PostService 4 | import com.example.demo.gql.types.Comment 5 | import com.example.demo.gql.types.CommentInput 6 | import com.example.demo.gql.types.CreatePostInput 7 | import com.example.demo.gql.types.Post 8 | import com.expediagroup.graphql.generator.annotations.GraphQLDescription 9 | import com.expediagroup.graphql.server.operations.Mutation 10 | import org.springframework.stereotype.Component 11 | import jakarta.validation.Valid 12 | 13 | @Component 14 | class Mutations(val postService: PostService) : Mutation { 15 | 16 | @GraphQLDescription("Create a new post") 17 | suspend fun createPost(@Valid input: CreatePostInput): Post { 18 | return postService.createPost(input) 19 | } 20 | 21 | @GraphQLDescription("Add comment to post") 22 | suspend fun addComment(@Valid input: CommentInput): Comment { 23 | return postService.addComment(input) 24 | } 25 | } -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/gql/datafetchers/Subscriptions.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.datafetchers 2 | 3 | import com.example.demo.service.PostService 4 | import com.example.demo.gql.types.Comment 5 | import com.expediagroup.graphql.server.operations.Subscription 6 | import kotlinx.coroutines.flow.Flow 7 | import org.springframework.stereotype.Component 8 | 9 | 10 | @Component 11 | class Subscriptions(val postService: PostService) : Subscription { 12 | 13 | fun commentAdded(): Flow { 14 | return postService.commentAdded() 15 | } 16 | } -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/gql/directives/UpperCase.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.directives 2 | 3 | import com.expediagroup.graphql.generator.annotations.GraphQLDirective 4 | import graphql.introspection.Introspection.DirectiveLocation.FIELD_DEFINITION 5 | 6 | @GraphQLDirective(name = UpperCaseDirectiveWiring.name, locations = [FIELD_DEFINITION]) 7 | annotation class UpperCase 8 | -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/gql/directives/UpperCaseDirectiveWiring.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.directives 2 | 3 | import com.expediagroup.graphql.generator.directives.KotlinFieldDirectiveEnvironment 4 | import com.expediagroup.graphql.generator.directives.KotlinSchemaDirectiveWiring 5 | import graphql.schema.DataFetcherFactories 6 | import graphql.schema.GraphQLFieldDefinition 7 | import java.util.* 8 | 9 | class UpperCaseDirectiveWiring : KotlinSchemaDirectiveWiring { 10 | companion object { 11 | const val name = "uppercase" 12 | } 13 | 14 | override fun onField(env: KotlinFieldDirectiveEnvironment): GraphQLFieldDefinition { 15 | 16 | val field = env.element 17 | val dataFetcher = DataFetcherFactories 18 | .wrapDataFetcher( 19 | env.getDataFetcher() 20 | ) { _, value -> if (value is String && value.isNotEmpty()) value.uppercase(Locale.getDefault()) else value } 21 | 22 | env.setDataFetcher(dataFetcher) 23 | return field 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/gql/exceptions/ValidationException.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.exceptions 2 | 3 | import jakarta.validation.ConstraintViolation 4 | 5 | class ValidationException(val constraintErrors: List) : RuntimeException("Validation error") 6 | 7 | data class ConstraintError(val path: String, val message: String, val type: String) 8 | 9 | fun ConstraintViolation<*>.asConstraintError() = ConstraintError( 10 | path = this.propertyPath.toString(), 11 | message = this.message, 12 | type = this.leafBean.toString() 13 | ) -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/gql/scalars/Scalars.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.scalars 2 | 3 | import graphql.schema.GraphQLScalarType 4 | 5 | 6 | object Scalars { 7 | val uuidType: GraphQLScalarType = GraphQLScalarType.newScalar() 8 | .name("UUID") 9 | .description("UUID type") 10 | .coercing(UUIDScalar()) 11 | .build() 12 | val localDateTimeType: GraphQLScalarType = GraphQLScalarType.newScalar() 13 | .name("LocalDateTime") 14 | .description("LocalDateTime type") 15 | .coercing(LocalDateTimeScalar()) 16 | .build() 17 | 18 | } 19 | 20 | -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/gql/types/Author.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types 2 | 3 | import java.time.LocalDateTime 4 | import java.util.* 5 | 6 | data class Author( 7 | val id: UUID?, 8 | val name: String, 9 | val email: String, 10 | val createdAt: LocalDateTime? = null, 11 | val posts: List? = emptyList() 12 | ) -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/gql/types/Comment.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types 2 | 3 | import java.time.LocalDateTime 4 | import java.util.* 5 | 6 | data class Comment( 7 | val id: UUID?, 8 | val content: String, 9 | val createdAt: LocalDateTime? = null, 10 | val postId: UUID? = null 11 | ) -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/gql/types/CommentInput.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types 2 | 3 | import java.util.* 4 | 5 | data class CommentInput( 6 | val content: String, 7 | val postId: UUID 8 | ) -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/gql/types/CreatePostInput.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types 2 | 3 | data class CreatePostInput( 4 | val title: String, 5 | val content: String, 6 | ) -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/model/AuthorEntity.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.model 2 | 3 | import org.springframework.data.annotation.CreatedDate 4 | import org.springframework.data.annotation.Id 5 | import org.springframework.data.relational.core.mapping.Column 6 | import org.springframework.data.relational.core.mapping.Table 7 | import java.time.LocalDateTime 8 | import java.util.* 9 | 10 | @Table(value = "users") 11 | data class AuthorEntity( 12 | @Id 13 | @Column("id") 14 | var id: UUID? = null, 15 | 16 | @Column("name") 17 | var name: String, 18 | 19 | @Column("email") 20 | var email: String, 21 | 22 | @Column("created_at") 23 | @CreatedDate 24 | var createdAt: LocalDateTime? = null, 25 | ) -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/model/CommentEntity.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.model 2 | 3 | import org.springframework.data.annotation.CreatedDate 4 | import org.springframework.data.annotation.Id 5 | import org.springframework.data.relational.core.mapping.Column 6 | import org.springframework.data.relational.core.mapping.Table 7 | import java.time.LocalDateTime 8 | import java.util.* 9 | 10 | @Table(value = "comments") 11 | data class CommentEntity( 12 | @Id 13 | @Column("id") 14 | var id: UUID? = null, 15 | 16 | @Column("content") 17 | var content: String, 18 | 19 | @Column("post_id") 20 | var postId: UUID? = null, 21 | 22 | @Column("created_at") 23 | @CreatedDate 24 | var createdAt: LocalDateTime? = null 25 | ) -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/model/PostStatus.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.model 2 | 3 | enum class PostStatus { 4 | DRAFT, PENDING_MODERATION, PUBLISHED 5 | } -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/repository/AuthorRepository.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.repository 2 | 3 | import com.example.demo.model.AuthorEntity 4 | import org.springframework.data.repository.kotlin.CoroutineCrudRepository 5 | import org.springframework.data.repository.kotlin.CoroutineSortingRepository 6 | import java.util.* 7 | 8 | interface AuthorRepository : CoroutineSortingRepository, 9 | CoroutineCrudRepository { 10 | suspend fun findOneByNameOrEmail(name: String, email: String): AuthorEntity 11 | } -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/repository/CommentRepository.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.repository 2 | 3 | import com.example.demo.model.CommentEntity 4 | import kotlinx.coroutines.flow.Flow 5 | import org.springframework.data.repository.kotlin.CoroutineCrudRepository 6 | import org.springframework.data.repository.kotlin.CoroutineSortingRepository 7 | import java.util.* 8 | 9 | interface CommentRepository : CoroutineSortingRepository, 10 | CoroutineCrudRepository { 11 | fun findByPostId(id: UUID): Flow 12 | fun findByPostIdIn(uuids: List): Flow 13 | } -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/repository/PostRepository.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.repository 2 | 3 | import com.example.demo.model.PostEntity 4 | import kotlinx.coroutines.flow.Flow 5 | import org.springframework.data.repository.kotlin.CoroutineCrudRepository 6 | import org.springframework.data.repository.kotlin.CoroutineSortingRepository 7 | import java.util.* 8 | 9 | interface PostRepository : CoroutineSortingRepository, 10 | CoroutineCrudRepository { 11 | fun findByAuthorId(id: UUID): Flow 12 | } -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/service/AuthorNotFoundException.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.service 2 | 3 | import java.util.* 4 | 5 | class AuthorNotFoundException(id: UUID) : RuntimeException("Author: $id was not found.") -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/service/AuthorService.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.service 2 | 3 | import com.example.demo.asGqlType 4 | import com.example.demo.gql.types.Author 5 | import com.example.demo.repository.AuthorRepository 6 | import kotlinx.coroutines.flow.Flow 7 | import kotlinx.coroutines.flow.map 8 | import org.springframework.stereotype.Service 9 | import java.util.* 10 | 11 | @Service 12 | class AuthorService(val authors: AuthorRepository) { 13 | 14 | suspend fun getAuthorById(id: UUID): Author { 15 | val author = this.authors.findById(id) ?: throw AuthorNotFoundException(id) 16 | return author.asGqlType() 17 | } 18 | 19 | // alternative to use kotlin `Flow` 20 | fun getAuthorByIdIn(ids: List): Flow { 21 | return authors.findAllById(ids.toList()).map { it.asGqlType() } 22 | } 23 | } -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/service/PostNotFoundException.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.service 2 | 3 | import java.util.* 4 | 5 | class PostNotFoundException(id: UUID) : RuntimeException("Post: $id was not found.") 6 | 7 | -------------------------------------------------------------------------------- /graphql-kotlin/src/main/kotlin/com/example/demo/service/PostService.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.service 2 | 3 | import com.example.demo.gql.types.Comment 4 | import com.example.demo.gql.types.CommentInput 5 | import com.example.demo.gql.types.CreatePostInput 6 | import com.example.demo.gql.types.Post 7 | import kotlinx.coroutines.flow.Flow 8 | import java.util.* 9 | 10 | interface PostService { 11 | fun allPosts(): Flow 12 | 13 | suspend fun getPostById(id: UUID): Post 14 | fun getPostsByAuthorId(id: UUID): Flow 15 | 16 | suspend fun createPost(postInput: CreatePostInput): Post 17 | 18 | suspend fun addComment(commentInput: CommentInput): Comment 19 | 20 | // subscription: commentAdded 21 | // use Flow instead of Publisher 22 | fun commentAdded(): Flow 23 | fun getCommentsByPostId(id: UUID): Flow 24 | fun getCommentsByPostIdIn(ids: Set): Flow 25 | 26 | fun getCommentsByPostsIn(ids: Set): Flow 27 | } -------------------------------------------------------------------------------- /graphql-kotlin/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | graphql.packages=com.example.demo.gql 2 | # Send a ka message every 1000 ms (1 second) 3 | graphql.subscriptions.keepAliveInterval=1000 4 | # APOLLO_SUBSCRIPTIONS_WS id deprecated 5 | graphql.subscriptions.protocol=GRAPHQL_WS 6 | graphql.print-schema=true 7 | 8 | logging.level.root=INFO 9 | logging.level.web=DEBUG 10 | logging.level.sql=DEBUG 11 | logging.level.com.example.demo=DEBUG 12 | logging.level.com.expediagroup.graphql.server.execution=DEBUG 13 | logging.level.org.springframework.r2dbc=DEBUG 14 | logging.level.reactor.core.publisher=TRACE 15 | 16 | spring.r2dbc.url=r2dbc:postgresql://localhost/blogdb 17 | spring.r2dbc.username=user 18 | spring.r2dbc.password=password 19 | spring.sql.init.mode=always -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/legacy/graphql-java-kickstart-annotations/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://repo.spring.io/milestone' } 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = 'graphql-java-annotations-example' 9 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/gql/CustomExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql; 2 | 3 | import com.example.demo.service.AuthorNotFoundException; 4 | import com.example.demo.service.PostNotFoundException; 5 | import graphql.kickstart.spring.error.ErrorContext; 6 | import graphql.kickstart.spring.error.ThrowableGraphQLError; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.web.bind.annotation.ExceptionHandler; 10 | 11 | @Component 12 | public class CustomExceptionHandler { 13 | 14 | @ExceptionHandler({AuthorNotFoundException.class, PostNotFoundException.class}) 15 | public ThrowableGraphQLError onException(Exception e, ErrorContext context) { 16 | return new ThrowableGraphQLError(e, HttpStatus.NOT_FOUND.getReasonPhrase()); 17 | } 18 | } -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/gql/dataloaders/AuthorsDataLoader.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.dataloaders; 2 | 3 | import com.example.demo.gql.types.Author; 4 | import com.example.demo.service.AuthorService; 5 | import lombok.RequiredArgsConstructor; 6 | import org.dataloader.BatchLoader; 7 | 8 | import java.util.List; 9 | import java.util.concurrent.CompletableFuture; 10 | import java.util.concurrent.CompletionStage; 11 | 12 | @RequiredArgsConstructor 13 | public class AuthorsDataLoader implements BatchLoader { 14 | final AuthorService authorService; 15 | 16 | @Override 17 | public CompletionStage> load(List keys) { 18 | return CompletableFuture.supplyAsync(() -> 19 | this.authorService.getAuthorByIdIn(keys) 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/gql/directives/UpperCaseDirective.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.directives; 2 | 3 | import graphql.annotations.annotationTypes.GraphQLDescription; 4 | import graphql.annotations.annotationTypes.GraphQLName; 5 | import graphql.annotations.annotationTypes.directives.definition.DirectiveLocations; 6 | import graphql.annotations.annotationTypes.directives.definition.GraphQLDirectiveDefinition; 7 | import graphql.introspection.Introspection; 8 | 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | 12 | @GraphQLName("upperCase") 13 | @GraphQLDescription("This directive makes a string uppercase") 14 | @GraphQLDirectiveDefinition(wiring = UpperCaseDirectiveWiring.class) 15 | @DirectiveLocations({Introspection.DirectiveLocation.FIELD_DEFINITION}) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | public @interface UpperCaseDirective {} -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/gql/resolvers/AuthorDataFetcher.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.resolvers; 2 | 3 | import com.example.demo.gql.types.Author; 4 | import com.example.demo.gql.types.Post; 5 | import graphql.schema.DataFetcher; 6 | import graphql.schema.DataFetchingEnvironment; 7 | import org.dataloader.DataLoader; 8 | 9 | import java.util.concurrent.CompletableFuture; 10 | 11 | public class AuthorDataFetcher implements DataFetcher> { 12 | 13 | @Override 14 | public CompletableFuture get(DataFetchingEnvironment dfe) throws Exception { 15 | DataLoader dataLoader = dfe.getDataLoader("authorsLoader"); 16 | Post post = dfe.getSource(); 17 | return dataLoader.load(post.getAuthorId()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/gql/resolvers/CommentsDataFetcher.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.resolvers; 2 | 3 | import com.example.demo.gql.types.Comment; 4 | import com.example.demo.gql.types.Post; 5 | import graphql.schema.DataFetcher; 6 | import graphql.schema.DataFetchingEnvironment; 7 | import org.dataloader.DataLoader; 8 | 9 | import java.util.List; 10 | import java.util.concurrent.CompletableFuture; 11 | 12 | public class CommentsDataFetcher implements DataFetcher>> { 13 | 14 | @Override 15 | public CompletableFuture> get(DataFetchingEnvironment dfe) throws Exception { 16 | DataLoader> dataLoader = dfe.getDataLoader("commentsLoader"); 17 | Post post = dfe.getSource(); 18 | return dataLoader.load(post.getId()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/gql/scalars/ScalarConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.scalars; 2 | 3 | import graphql.schema.GraphQLScalarType; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | public class ScalarConfig { 9 | 10 | @Bean 11 | GraphQLScalarType uuidType() { 12 | return GraphQLScalarType.newScalar() 13 | .name("UUID") 14 | .description("UUID type") 15 | .coercing(new UUIDScalar()) 16 | .build(); 17 | } 18 | 19 | @Bean 20 | GraphQLScalarType localDateTimeType() { 21 | return GraphQLScalarType.newScalar() 22 | .name("LocalDateTime") 23 | .description("LocalDateTime type") 24 | .coercing(new LocalDateTimeScalar()) 25 | .build(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/gql/types/Author.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import graphql.annotations.annotationTypes.*; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | import java.time.LocalDateTime; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | @Data 14 | @Builder 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class Author { 18 | 19 | @GraphQLID 20 | @GraphQLField 21 | @GraphQLNonNull 22 | private String id; 23 | 24 | @GraphQLField 25 | @GraphQLNonNull 26 | private String name; 27 | 28 | @GraphQLField 29 | @GraphQLNonNull 30 | private String email; 31 | 32 | @GraphQLField 33 | private LocalDateTime createdAt; 34 | 35 | @Builder.Default 36 | @GraphQLField 37 | private List posts = new ArrayList<>(); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/gql/types/Comment.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import graphql.annotations.annotationTypes.GraphQLField; 4 | import graphql.annotations.annotationTypes.GraphQLID; 5 | import graphql.annotations.annotationTypes.GraphQLNonNull; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | import java.time.LocalDateTime; 12 | 13 | @Data 14 | @Builder 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class Comment { 18 | 19 | @GraphQLID 20 | @GraphQLField 21 | @GraphQLNonNull 22 | private String id; 23 | 24 | @GraphQLField 25 | @GraphQLNonNull 26 | private String content; 27 | 28 | @GraphQLField 29 | private LocalDateTime createdAt; 30 | 31 | @GraphQLField 32 | private String postId; 33 | } 34 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/gql/types/CommentInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import graphql.annotations.annotationTypes.GraphQLConstructor; 4 | import graphql.annotations.annotationTypes.GraphQLField; 5 | import graphql.annotations.annotationTypes.GraphQLNonNull; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | @Data 12 | @Builder 13 | @NoArgsConstructor 14 | @AllArgsConstructor(onConstructor_ = @GraphQLConstructor) 15 | public class CommentInput { 16 | @GraphQLField 17 | @GraphQLNonNull 18 | private String postId; 19 | 20 | @GraphQLField 21 | @GraphQLNonNull 22 | private String content; 23 | } 24 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/gql/types/CreatePostInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import graphql.annotations.annotationTypes.GraphQLConstructor; 4 | import graphql.annotations.annotationTypes.GraphQLField; 5 | import graphql.annotations.annotationTypes.GraphQLNonNull; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | @Data 12 | @Builder 13 | @NoArgsConstructor 14 | @AllArgsConstructor(onConstructor_ = @GraphQLConstructor) 15 | public class CreatePostInput { 16 | @GraphQLField 17 | @GraphQLNonNull 18 | private String title; 19 | @GraphQLField 20 | @GraphQLNonNull 21 | private String content; 22 | } 23 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/gql/types/PostStatus.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | public enum PostStatus { 4 | DRAFT, 5 | PENDING_MODERATION, 6 | PUBLISHED 7 | } 8 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/model/AuthorEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record AuthorEntity( 7 | UUID id, 8 | String name, 9 | String email, 10 | LocalDateTime createdAt 11 | ) { 12 | } 13 | 14 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/model/CommentEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record CommentEntity( 7 | UUID id, 8 | String content, 9 | LocalDateTime createdAt, 10 | UUID postId 11 | ) { 12 | } 13 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/model/PostEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record PostEntity( 7 | UUID id, 8 | String title, 9 | String content, 10 | String status, 11 | LocalDateTime createdAt, 12 | UUID authorId 13 | ) { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/service/AuthorNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class AuthorNotFoundException extends RuntimeException { 4 | public AuthorNotFoundException(String id) { 5 | super("Author: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/java/com/example/demo/service/PostNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class PostNotFoundException extends RuntimeException { 4 | public PostNotFoundException(String id) { 5 | super("Post: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-annotations/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:postgresql://localhost/blogdb 2 | spring.datasource.username=user 3 | spring.datasource.password=password 4 | spring.sql.init.mode=always 5 | 6 | graphql.annotations.base-package=com.example.demo.gql 7 | graphql.annotations.always-prettify=true 8 | graphql.annotations.input-prefix= 9 | graphql.annotations.input-suffix= 10 | 11 | graphql.schema-strategy=annotations 12 | graphql.servlet.mapping=/graphql 13 | # 14 | # Logging level 15 | # 16 | logging.level.com.example=DEBUG 17 | logging.level.org.springframework.jdbc=DEBUG 18 | logging.level.web=DEBUG 19 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-webclient/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-webclient/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/legacy/graphql-java-kickstart-webclient/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-webclient/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-webclient/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://repo.spring.io/milestone' } 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = 'graphql-java-webclient-example' 9 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-webclient/src/main/java/com/example/demo/gql/types/Author.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class Author { 17 | private String id; 18 | 19 | private String name; 20 | 21 | private String email; 22 | 23 | private LocalDateTime createdAt; 24 | 25 | @Builder.Default 26 | private List posts = new ArrayList<>(); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-webclient/src/main/java/com/example/demo/gql/types/Comment.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | 10 | @Data 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class Comment { 15 | private String id; 16 | private String content; 17 | private LocalDateTime createdAt; 18 | private String postId; 19 | } 20 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-webclient/src/main/java/com/example/demo/gql/types/CommentInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @Builder 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class CommentInput { 13 | private String postId; 14 | private String content; 15 | } 16 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-webclient/src/main/java/com/example/demo/gql/types/CreatePostInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @Builder 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class CreatePostInput { 13 | private String title; 14 | private String content; 15 | } 16 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-webclient/src/main/java/com/example/demo/gql/types/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class Post { 17 | private String id; 18 | private String title; 19 | private String content; 20 | @Builder.Default 21 | private List comments= new ArrayList<>(); 22 | private PostStatus status; 23 | private LocalDateTime createdAt; 24 | private String authorId; 25 | private Author author; 26 | } 27 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-webclient/src/main/java/com/example/demo/gql/types/PostStatus.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | public enum PostStatus { 4 | DRAFT, 5 | PENDING_MODERATION, 6 | PUBLISHED 7 | } 8 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-webclient/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | graphql.client.url=http://localhost:8080/graphql 2 | # 3 | # Logging level 4 | # 5 | logging.level.com.example=DEBUG 6 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-webclient/src/main/resources/fileupload.gql: -------------------------------------------------------------------------------- 1 | mutation upload($file:Upload!){ upload(file:$file) } -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart-webclient/src/main/resources/test.txt: -------------------------------------------------------------------------------- 1 | test content -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/legacy/graphql-java-kickstart/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://repo.spring.io/milestone' } 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = 'graphql-java-kickstart-example' 9 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/CustomExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql; 2 | 3 | import com.example.demo.service.AuthorNotFoundException; 4 | import com.example.demo.service.PostNotFoundException; 5 | import graphql.kickstart.spring.error.ErrorContext; 6 | import graphql.kickstart.spring.error.ThrowableGraphQLError; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.web.bind.annotation.ExceptionHandler; 10 | 11 | @Component 12 | public class CustomExceptionHandler { 13 | 14 | @ExceptionHandler({AuthorNotFoundException.class, PostNotFoundException.class}) 15 | public ThrowableGraphQLError onException(Exception e, ErrorContext context) { 16 | return new ThrowableGraphQLError(e, HttpStatus.NOT_FOUND.getReasonPhrase()); 17 | } 18 | } -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/dataloaders/AuthorsDataLoader.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.dataloaders; 2 | 3 | import com.example.demo.gql.types.Author; 4 | import com.example.demo.service.AuthorService; 5 | import lombok.RequiredArgsConstructor; 6 | import org.dataloader.BatchLoader; 7 | 8 | import java.util.List; 9 | import java.util.concurrent.CompletableFuture; 10 | import java.util.concurrent.CompletionStage; 11 | 12 | @RequiredArgsConstructor 13 | public class AuthorsDataLoader implements BatchLoader { 14 | final AuthorService authorService; 15 | 16 | @Override 17 | public CompletionStage> load(List keys) { 18 | return CompletableFuture.supplyAsync(() -> 19 | this.authorService.getAuthorByIdIn(keys) 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/directives/DirectiveConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.directives; 2 | 3 | import graphql.kickstart.autoconfigure.tools.SchemaDirective; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | public class DirectiveConfig { 9 | 10 | @Bean 11 | SchemaDirective uppercaseDirective(){ 12 | return new SchemaDirective("uppercase", new UppercaseDirective()); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/resolvers/AddCommentMutationResolver.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.resolvers; 2 | 3 | import com.example.demo.gql.types.CommentInput; 4 | import com.example.demo.service.PostService; 5 | import graphql.kickstart.tools.GraphQLMutationResolver; 6 | import lombok.RequiredArgsConstructor; 7 | import lombok.SneakyThrows; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.stereotype.Component; 10 | import org.springframework.util.StreamUtils; 11 | 12 | import jakarta.servlet.http.Part; 13 | import java.nio.charset.StandardCharsets; 14 | import java.util.UUID; 15 | 16 | @RequiredArgsConstructor 17 | @Slf4j 18 | @Component 19 | public class AddCommentMutationResolver implements GraphQLMutationResolver { 20 | final PostService postService; 21 | 22 | public UUID addComment(CommentInput commentInput) { 23 | return this.postService.addComment(commentInput); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/resolvers/AllPostQueryResolver.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.resolvers; 2 | 3 | import com.example.demo.gql.types.Post; 4 | import com.example.demo.service.PostService; 5 | import graphql.kickstart.tools.GraphQLQueryResolver; 6 | import lombok.RequiredArgsConstructor; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.util.List; 10 | 11 | @RequiredArgsConstructor 12 | @Component 13 | public class AllPostQueryResolver implements GraphQLQueryResolver { 14 | final PostService postService; 15 | 16 | public List allPosts() { 17 | return this.postService.getAllPosts(); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/resolvers/AuthorResolver.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.resolvers; 2 | 3 | import com.example.demo.gql.types.Author; 4 | import com.example.demo.gql.types.Post; 5 | import graphql.kickstart.tools.GraphQLResolver; 6 | import graphql.schema.DataFetchingEnvironment; 7 | import org.dataloader.DataLoader; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.util.concurrent.CompletableFuture; 11 | 12 | @Component 13 | public class AuthorResolver implements GraphQLResolver { 14 | 15 | public CompletableFuture author(Post post, DataFetchingEnvironment dfe) { 16 | DataLoader dataLoader = dfe.getDataLoader("authorsLoader"); 17 | // Post post = dfe.getSource(); 18 | return dataLoader.load(post.getAuthorId()); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/resolvers/CommentAddedSubscriptionResolver.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.resolvers; 2 | 3 | import com.example.demo.gql.types.Comment; 4 | import com.example.demo.service.PostService; 5 | import graphql.kickstart.tools.GraphQLSubscriptionResolver; 6 | import lombok.RequiredArgsConstructor; 7 | import org.reactivestreams.Publisher; 8 | import org.springframework.stereotype.Component; 9 | 10 | @Component 11 | @RequiredArgsConstructor 12 | public class CommentAddedSubscriptionResolver implements GraphQLSubscriptionResolver { 13 | final PostService postService; 14 | Publisher commentAdded(){ 15 | return postService.commentAdded(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/resolvers/CommentsResolver.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.resolvers; 2 | 3 | import com.example.demo.gql.types.Comment; 4 | import com.example.demo.gql.types.Post; 5 | import graphql.kickstart.tools.GraphQLResolver; 6 | import graphql.schema.DataFetchingEnvironment; 7 | import org.dataloader.DataLoader; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.util.List; 11 | import java.util.concurrent.CompletableFuture; 12 | 13 | @Component 14 | public class CommentsResolver implements GraphQLResolver { 15 | 16 | public CompletableFuture> comments(Post post, DataFetchingEnvironment dfe) { 17 | DataLoader> dataLoader = dfe.getDataLoader("commentsLoader"); 18 | //Post post = dfe.getSource(); 19 | return dataLoader.load(post.getId()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/resolvers/CreatePostMutationResolver.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.resolvers; 2 | 3 | import com.example.demo.gql.types.CreatePostInput; 4 | import com.example.demo.service.PostService; 5 | import graphql.kickstart.tools.GraphQLMutationResolver; 6 | import lombok.RequiredArgsConstructor; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.util.UUID; 10 | 11 | @RequiredArgsConstructor 12 | @Component 13 | public class CreatePostMutationResolver implements GraphQLMutationResolver { 14 | final PostService postService; 15 | public UUID createPost(CreatePostInput input) { 16 | return this.postService.createPost(input); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/resolvers/PostByIdQueryResolver.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.resolvers; 2 | 3 | import com.example.demo.gql.types.Post; 4 | import com.example.demo.service.PostService; 5 | import graphql.kickstart.tools.GraphQLQueryResolver; 6 | import lombok.RequiredArgsConstructor; 7 | import org.springframework.stereotype.Component; 8 | 9 | @RequiredArgsConstructor 10 | @Component 11 | public class PostByIdQueryResolver implements GraphQLQueryResolver { 12 | final PostService postService; 13 | 14 | public Post postById(String postId) { 15 | return this.postService.getPostById(postId); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/types/Author.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class Author { 17 | private String id; 18 | 19 | private String name; 20 | 21 | private String email; 22 | 23 | private LocalDateTime createdAt; 24 | 25 | @Builder.Default 26 | private List posts = new ArrayList<>(); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/types/Comment.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | 10 | @Data 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class Comment { 15 | private String id; 16 | private String content; 17 | private LocalDateTime createdAt; 18 | private String postId; 19 | } 20 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/types/CommentInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @Builder 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class CommentInput { 13 | private String postId; 14 | private String content; 15 | } 16 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/types/CreatePostInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @Builder 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class CreatePostInput { 13 | private String title; 14 | private String content; 15 | } 16 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/types/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class Post { 17 | private String id; 18 | private String title; 19 | private String content; 20 | @Builder.Default 21 | private List comments= new ArrayList<>(); 22 | private PostStatus status; 23 | private LocalDateTime createdAt; 24 | private String authorId; 25 | private Author author; 26 | } 27 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/gql/types/PostStatus.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | public enum PostStatus { 4 | DRAFT, 5 | PENDING_MODERATION, 6 | PUBLISHED 7 | } 8 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/model/AuthorEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record AuthorEntity( 7 | UUID id, 8 | String name, 9 | String email, 10 | LocalDateTime createdAt 11 | ) { 12 | } 13 | 14 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/model/CommentEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record CommentEntity( 7 | UUID id, 8 | String content, 9 | LocalDateTime createdAt, 10 | UUID postId 11 | ) { 12 | } 13 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/model/PostEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record PostEntity( 7 | UUID id, 8 | String title, 9 | String content, 10 | String status, 11 | LocalDateTime createdAt, 12 | UUID authorId 13 | ) { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/service/AuthorNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class AuthorNotFoundException extends RuntimeException { 4 | public AuthorNotFoundException(String id) { 5 | super("Author: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/java/com/example/demo/service/PostNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class PostNotFoundException extends RuntimeException { 4 | public PostNotFoundException(String id) { 5 | super("Post: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:postgresql://localhost/blogdb 2 | spring.datasource.username=user 3 | spring.datasource.password=password 4 | spring.sql.init.mode=always 5 | 6 | graphql.tools.schema-location-pattern=**/schema.graphql 7 | graphql.tools.introspection-enabled=true 8 | # 9 | # Logging level 10 | # 11 | logging.level.com.example=DEBUG 12 | logging.level.org.springframework.jdbc=DEBUG 13 | logging.level.web=DEBUG 14 | -------------------------------------------------------------------------------- /legacy/graphql-java-kickstart/src/test/resources/test.txt: -------------------------------------------------------------------------------- 1 | test content 2 | -------------------------------------------------------------------------------- /legacy/graphql-java/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /legacy/graphql-java/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/legacy/graphql-java/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /legacy/graphql-java/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /legacy/graphql-java/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://repo.spring.io/milestone' } 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = 'graphql-java-example' 9 | -------------------------------------------------------------------------------- /legacy/graphql-java/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /legacy/graphql-java/src/main/java/com/example/demo/gql/scalars/Scalars.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.scalars; 2 | 3 | import graphql.schema.GraphQLScalarType; 4 | 5 | public class Scalars { 6 | 7 | public static GraphQLScalarType uuidType() { 8 | return GraphQLScalarType.newScalar() 9 | .name("UUID") 10 | .description("UUID type") 11 | .coercing(new UUIDScalar()) 12 | .build(); 13 | } 14 | 15 | public static GraphQLScalarType localDateTimeType() { 16 | return GraphQLScalarType.newScalar() 17 | .name("LocalDateTime") 18 | .description("LocalDateTime type") 19 | .coercing(new LocalDateTimeScalar()) 20 | .build(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /legacy/graphql-java/src/main/java/com/example/demo/gql/types/Author.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class Author { 17 | private String id; 18 | 19 | private String name; 20 | 21 | private String email; 22 | 23 | private LocalDateTime createdAt; 24 | 25 | @Builder.Default 26 | private List posts = new ArrayList<>(); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /legacy/graphql-java/src/main/java/com/example/demo/gql/types/Comment.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | 10 | @Data 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class Comment { 15 | private String id; 16 | private String content; 17 | private LocalDateTime createdAt; 18 | private String postId; 19 | } 20 | -------------------------------------------------------------------------------- /legacy/graphql-java/src/main/java/com/example/demo/gql/types/CommentInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @Builder 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class CommentInput { 13 | private String postId; 14 | private String content; 15 | } 16 | -------------------------------------------------------------------------------- /legacy/graphql-java/src/main/java/com/example/demo/gql/types/CreatePostInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @Builder 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class CreatePostInput { 13 | private String title; 14 | private String content; 15 | } 16 | -------------------------------------------------------------------------------- /legacy/graphql-java/src/main/java/com/example/demo/gql/types/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class Post { 17 | private String id; 18 | private String title; 19 | private String content; 20 | @Builder.Default 21 | private List comments= new ArrayList<>(); 22 | private PostStatus status; 23 | private LocalDateTime createdAt; 24 | private String authorId; 25 | private Author author; 26 | } 27 | -------------------------------------------------------------------------------- /legacy/graphql-java/src/main/java/com/example/demo/gql/types/PostStatus.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | public enum PostStatus { 4 | DRAFT, 5 | PENDING_MODERATION, 6 | PUBLISHED 7 | } 8 | -------------------------------------------------------------------------------- /legacy/graphql-java/src/main/java/com/example/demo/model/AuthorEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record AuthorEntity( 7 | UUID id, 8 | String name, 9 | String email, 10 | LocalDateTime createdAt 11 | ) { 12 | } 13 | 14 | -------------------------------------------------------------------------------- /legacy/graphql-java/src/main/java/com/example/demo/model/CommentEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record CommentEntity( 7 | UUID id, 8 | String content, 9 | LocalDateTime createdAt, 10 | UUID postId 11 | ) { 12 | } 13 | -------------------------------------------------------------------------------- /legacy/graphql-java/src/main/java/com/example/demo/model/PostEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record PostEntity( 7 | UUID id, 8 | String title, 9 | String content, 10 | String status, 11 | LocalDateTime createdAt, 12 | UUID authorId 13 | ) { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /legacy/graphql-java/src/main/java/com/example/demo/service/AuthorNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class AuthorNotFoundException extends RuntimeException { 4 | public AuthorNotFoundException(String id) { 5 | super("Author: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /legacy/graphql-java/src/main/java/com/example/demo/service/PostNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class PostNotFoundException extends RuntimeException { 4 | public PostNotFoundException(String id) { 5 | super("Post: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /legacy/graphql-java/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:postgresql://localhost/blogdb 2 | spring.datasource.username=user 3 | spring.datasource.password=password 4 | spring.sql.init.mode=always 5 | logging.level.com.example=DEBUG 6 | logging.level.org.springframework.jdbc=DEBUG 7 | logging.level.web=DEBUG 8 | # logging.level.graphql=DEBUG 9 | -------------------------------------------------------------------------------- /legacy/graphql-java/src/main/resources/schema/schema.graphql: -------------------------------------------------------------------------------- 1 | directive @uppercase on FIELD_DEFINITION 2 | 3 | scalar LocalDateTime 4 | scalar UUID 5 | 6 | type Post{ 7 | id: ID! 8 | title: String! @uppercase 9 | content: String 10 | comments: [Comment] 11 | status: PostStatus 12 | createdAt: LocalDateTime 13 | authorId:String 14 | author:Author 15 | } 16 | 17 | type Author{ 18 | id:ID! 19 | name:String! 20 | email:String! 21 | createdAt: LocalDateTime 22 | posts: [Post] 23 | } 24 | type Comment{ 25 | id: ID! 26 | content: String! 27 | createdAt: LocalDateTime 28 | postId: String! 29 | } 30 | 31 | input CreatePostInput { 32 | title: String! 33 | content: String! 34 | } 35 | 36 | input CommentInput{ 37 | postId: String! 38 | content: String! 39 | } 40 | 41 | type Query { 42 | allPosts: [Post!]! 43 | postById(postId: String!): Post 44 | } 45 | 46 | type Mutation { 47 | createPost(createPostInput: CreatePostInput!): UUID! 48 | } 49 | 50 | enum PostStatus { 51 | DRAFT, PENDING_MODERATION, PUBLISHED 52 | } 53 | 54 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/legacy/graphql-spqr/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /legacy/graphql-spqr/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://repo.spring.io/milestone' } 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = 'graphql-spqr-example' 9 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/src/main/java/com/example/demo/gql/dataloaders/AuthorsDataLoader.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.dataloaders; 2 | 3 | import com.example.demo.gql.types.Author; 4 | import com.example.demo.service.AuthorService; 5 | import lombok.RequiredArgsConstructor; 6 | import org.dataloader.BatchLoader; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.util.List; 10 | import java.util.concurrent.CompletableFuture; 11 | import java.util.concurrent.CompletionStage; 12 | 13 | @RequiredArgsConstructor 14 | @Component 15 | public class AuthorsDataLoader implements BatchLoader { 16 | final AuthorService authorService; 17 | 18 | @Override 19 | public CompletionStage> load(List keys) { 20 | return CompletableFuture.supplyAsync(() -> 21 | this.authorService.getAuthorByIdIn(keys) 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/src/main/java/com/example/demo/gql/dataloaders/SimpleDataLoaderRegistryFactory.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.dataloaders; 2 | 3 | import io.leangen.graphql.spqr.spring.autoconfigure.DataLoaderRegistryFactory; 4 | import lombok.RequiredArgsConstructor; 5 | import org.dataloader.DataLoaderFactory; 6 | import org.dataloader.DataLoaderRegistry; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | @RequiredArgsConstructor 11 | public class SimpleDataLoaderRegistryFactory implements DataLoaderRegistryFactory { 12 | private final AuthorsDataLoader authorsDataLoader; 13 | private final CommentsDataLoader commentsDataLoader; 14 | 15 | @Override 16 | public DataLoaderRegistry createDataLoaderRegistry() { 17 | DataLoaderRegistry loaders = new DataLoaderRegistry(); 18 | loaders.register("authorsDataLoader", DataLoaderFactory.newDataLoader(authorsDataLoader)); 19 | loaders.register("commentsDataLoader", DataLoaderFactory.newMappedDataLoader(commentsDataLoader)); 20 | 21 | return loaders; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/src/main/java/com/example/demo/gql/types/Author.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import io.leangen.graphql.annotations.GraphQLId; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.ToString; 7 | 8 | @Data 9 | @Builder 10 | @ToString 11 | public class Author { 12 | 13 | @GraphQLId 14 | String id; 15 | String name; 16 | String email; 17 | } 18 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/src/main/java/com/example/demo/gql/types/Comment.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import io.leangen.graphql.annotations.GraphQLId; 4 | import lombok.*; 5 | 6 | @Data 7 | @Builder 8 | @ToString 9 | @NoArgsConstructor 10 | @AllArgsConstructor 11 | public class Comment { 12 | @GraphQLId 13 | String id; 14 | String postId; 15 | String content; 16 | } 17 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/src/main/java/com/example/demo/gql/types/CreateComment.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.*; 4 | import org.hibernate.validator.constraints.Length; 5 | 6 | import jakarta.validation.constraints.NotEmpty; 7 | 8 | @Data 9 | @Builder 10 | @ToString 11 | @NoArgsConstructor 12 | @AllArgsConstructor(staticName = "of") 13 | public class CreateComment { 14 | 15 | @NotEmpty 16 | String postId; 17 | 18 | @NotEmpty 19 | @Length(min = 10, max = 50) 20 | String content; 21 | } 22 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/src/main/java/com/example/demo/gql/types/CreatePost.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import io.leangen.graphql.annotations.GraphQLInputField; 4 | import lombok.*; 5 | import org.hibernate.validator.constraints.Length; 6 | 7 | import jakarta.validation.constraints.NotEmpty; 8 | 9 | @Data 10 | @Builder 11 | @ToString 12 | @NoArgsConstructor 13 | @AllArgsConstructor(staticName = "of") 14 | // The generator will add `Input` postfix automatically. 15 | public class CreatePost { 16 | @NotEmpty 17 | @Length(min = 5, max = 100) 18 | @GraphQLInputField 19 | String title; 20 | 21 | @NotEmpty 22 | @GraphQLInputField 23 | String content; 24 | } 25 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/src/main/java/com/example/demo/gql/types/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import io.leangen.graphql.annotations.GraphQLId; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.ToString; 7 | import lombok.extern.slf4j.Slf4j; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | @Data 13 | @Builder 14 | @ToString 15 | @Slf4j 16 | public class Post { 17 | @GraphQLId 18 | String id; 19 | String title; 20 | String content; 21 | @Builder.Default 22 | PostStatus status = PostStatus.DRAFT; 23 | @Builder.Default 24 | List comments = new ArrayList<>(); 25 | String authorId; 26 | Author author; 27 | 28 | public void addComment(Comment comment) { 29 | comment.setPostId(this.id); 30 | this.comments.add(comment); 31 | log.info("post comments: {}", this.comments); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/src/main/java/com/example/demo/gql/types/PostStatus.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | public enum PostStatus { 4 | DRAFT, PUBLISHED; 5 | } 6 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/src/main/java/com/example/demo/model/AuthorEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.util.UUID; 4 | 5 | public record AuthorEntity( 6 | UUID id, 7 | String name, 8 | String email 9 | ) { 10 | } 11 | 12 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/src/main/java/com/example/demo/model/CommentEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.util.UUID; 4 | 5 | public record CommentEntity( 6 | UUID id, 7 | String content, 8 | UUID postId 9 | ) { 10 | } 11 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/src/main/java/com/example/demo/model/PostEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record PostEntity( 7 | UUID id, 8 | String title, 9 | String content, 10 | String status, 11 | UUID authorId 12 | ) { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/src/main/java/com/example/demo/service/AuthorNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class AuthorNotFoundException extends RuntimeException { 4 | public AuthorNotFoundException(String id) { 5 | super("Author: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/src/main/java/com/example/demo/service/PostNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class PostNotFoundException extends RuntimeException { 4 | public PostNotFoundException(String id) { 5 | super("Post: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /legacy/graphql-spqr/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:postgresql://localhost/blogdb 2 | spring.datasource.username=user 3 | spring.datasource.password=password 4 | spring.sql.init.mode=always 5 | #dgs.graphql.schema-locations[0]= 6 | 7 | logging.level.root=INFO 8 | logging.level.com.example=DEBUG 9 | logging.level.web=DEBUG 10 | logging.level.io.leangen.graphql=DEBUG 11 | 12 | spring.mvc.async.request-timeout=45000 13 | graphql.spqr.gui.enabled=true 14 | graphql.spqr.relay.connection-check-relaxed=true 15 | graphql.spqr.relay.spring-data-compatible=false 16 | spring.data.rest.default-page-size=20 17 | spring.mvc.converters.preferred-json-mapper=jackson -------------------------------------------------------------------------------- /spring-graphql-querydsl/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /spring-graphql-querydsl/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/spring-graphql-querydsl/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /spring-graphql-querydsl/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /spring-graphql-querydsl/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://repo.spring.io/milestone' } 4 | gradlePluginPortal() 5 | } 6 | } 7 | rootProject.name = 'spring-graphql-querydsl-example' 8 | -------------------------------------------------------------------------------- /spring-graphql-querydsl/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-graphql-querydsl/src/main/java/com/example/demo/gql/scalars/Scalars.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.scalars; 2 | 3 | import graphql.schema.GraphQLScalarType; 4 | 5 | public class Scalars { 6 | 7 | public static GraphQLScalarType uuidType() { 8 | return GraphQLScalarType.newScalar() 9 | .name("UUID") 10 | .description("UUID type") 11 | .coercing(new UUIDScalar()) 12 | .build(); 13 | } 14 | 15 | public static GraphQLScalarType localDateTimeType() { 16 | return GraphQLScalarType.newScalar() 17 | .name("LocalDateTime") 18 | .description("LocalDateTime type") 19 | .coercing(new LocalDateTimeScalar()) 20 | .build(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /spring-graphql-querydsl/src/main/java/com/example/demo/model/Comment.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import jakarta.persistence.*; 9 | import java.time.LocalDateTime; 10 | import java.util.UUID; 11 | 12 | @Entity 13 | @Table(name = "comments") 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | @Builder 18 | public class Comment { 19 | 20 | @Id 21 | @GeneratedValue 22 | private UUID id; 23 | private String content; 24 | 25 | @Column(name = "created_at") 26 | private LocalDateTime createdAt; 27 | 28 | @ManyToOne 29 | @JoinColumn(name = "post_id") 30 | private Post post; 31 | 32 | @Override 33 | public String toString() { 34 | return "Comment{" + 35 | "id=" + id + 36 | ", content='" + content + '\'' + 37 | ", createdAt=" + createdAt + 38 | ", post=" + post.getId() + 39 | '}'; 40 | } 41 | } -------------------------------------------------------------------------------- /spring-graphql-querydsl/src/main/java/com/example/demo/model/PostStatus.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | public enum PostStatus { 4 | DRAFT, PUBLISHED 5 | } 6 | -------------------------------------------------------------------------------- /spring-graphql-querydsl/src/main/java/com/example/demo/repository/CommentRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.repository; 2 | 3 | import com.example.demo.model.Comment; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.UUID; 7 | 8 | public interface CommentRepository extends JpaRepository { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /spring-graphql-querydsl/src/main/java/com/example/demo/repository/PostRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.repository; 2 | 3 | import com.example.demo.model.Post; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.data.querydsl.QuerydslPredicateExecutor; 6 | import org.springframework.graphql.data.GraphQlRepository; 7 | 8 | import java.util.UUID; 9 | 10 | //@GraphQlRepository() 11 | public interface PostRepository extends JpaRepository , 12 | QuerydslPredicateExecutor { 13 | 14 | } -------------------------------------------------------------------------------- /spring-graphql-querydsl/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:postgresql://localhost/blogdb 2 | spring.datasource.username=user 3 | spring.datasource.password=password 4 | spring.sql.init.mode=always 5 | 6 | #spring.graphql.schema.locations= 7 | # 8 | # Logging level 9 | # 10 | logging.level.com.example=DEBUG 11 | logging.level.org.springframework.jdbc=DEBUG 12 | logging.level.web=DEBUG 13 | -------------------------------------------------------------------------------- /spring-graphql-querydsl/src/main/resources/graphql/schema.graphqls: -------------------------------------------------------------------------------- 1 | directive @uppercase on FIELD_DEFINITION 2 | 3 | scalar LocalDateTime 4 | scalar UUID 5 | #scalar Upload 6 | 7 | type Post{ 8 | id: ID! 9 | title: String! @uppercase 10 | content: String 11 | comments: [Comment] 12 | status: PostStatus 13 | createdAt: LocalDateTime 14 | } 15 | 16 | type Comment{ 17 | id: ID! 18 | content: String! 19 | createdAt: LocalDateTime 20 | postId: String! 21 | } 22 | 23 | 24 | type Query { 25 | posts: [Post!] 26 | post(id: ID!): Post 27 | } 28 | 29 | enum PostStatus { 30 | DRAFT, PENDING_MODERATION, PUBLISHED 31 | } 32 | 33 | -------------------------------------------------------------------------------- /spring-graphql-rsocket-kotlin-co/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /spring-graphql-rsocket-kotlin-co/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/spring-graphql-rsocket-kotlin-co/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /spring-graphql-rsocket-kotlin-co/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /spring-graphql-rsocket-kotlin-co/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url = uri("https://repo.spring.io/milestone") } 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = "spring-graphql-rsocket-sample" 9 | -------------------------------------------------------------------------------- /spring-graphql-rsocket-kotlin-co/src/main/kotlin/com/example/demo/Extensions.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo 2 | 3 | import com.example.demo.gql.types.Author 4 | import com.example.demo.gql.types.Comment 5 | import com.example.demo.gql.types.Post 6 | 7 | fun PostEntity.asGqlType(): Post = Post( 8 | id = this.id, 9 | title = this.title, 10 | content = this.content, 11 | status = this.status, 12 | createdAt = this.createdAt, 13 | authorId = this.authorId 14 | ) 15 | 16 | fun CommentEntity.asGqlType(): Comment = Comment( 17 | id = this.id, 18 | content = this.content, 19 | createdAt = this.createdAt, 20 | postId = this.postId 21 | ) 22 | 23 | fun AuthorEntity.asGqlType(): Author = Author( 24 | id = this.id, 25 | name = this.name, 26 | email = this.email, 27 | createdAt = this.createdAt 28 | ) -------------------------------------------------------------------------------- /spring-graphql-rsocket-kotlin-co/src/main/kotlin/com/example/demo/Repositories.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo 2 | 3 | import kotlinx.coroutines.flow.Flow 4 | import org.springframework.data.repository.kotlin.CoroutineCrudRepository 5 | import org.springframework.data.repository.kotlin.CoroutineSortingRepository 6 | import java.util.UUID 7 | 8 | interface AuthorRepository : CoroutineSortingRepository, 9 | CoroutineCrudRepository { 10 | suspend fun findByNameOrEmail(name: String, email: String): AuthorEntity 11 | } 12 | 13 | interface CommentRepository : CoroutineSortingRepository, 14 | CoroutineCrudRepository { 15 | fun findByPostId(id: UUID): Flow 16 | fun findByPostIdIn(uuids: List): Flow 17 | } 18 | 19 | interface PostRepository : CoroutineSortingRepository, 20 | CoroutineCrudRepository { 21 | fun findByAuthorId(id: UUID): Flow 22 | } -------------------------------------------------------------------------------- /spring-graphql-rsocket-kotlin-co/src/main/kotlin/com/example/demo/gql/ExceptionHandlers.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql 2 | 3 | import com.example.demo.AuthorNotFoundException 4 | import com.example.demo.PostNotFoundException 5 | import graphql.GraphQLError 6 | import graphql.GraphqlErrorBuilder 7 | import graphql.schema.DataFetchingEnvironment 8 | import org.springframework.graphql.execution.DataFetcherExceptionResolverAdapter 9 | import org.springframework.graphql.execution.ErrorType 10 | import org.springframework.stereotype.Component 11 | 12 | @Component 13 | class ExceptionHandlers : DataFetcherExceptionResolverAdapter() { 14 | override fun resolveToSingleError(ex: Throwable, env: DataFetchingEnvironment): GraphQLError? { 15 | return when (ex) { 16 | is PostNotFoundException, is AuthorNotFoundException -> GraphqlErrorBuilder.newError(env) 17 | .errorType(ErrorType.NOT_FOUND) 18 | .message(ex.message) 19 | .build() 20 | else -> super.resolveToSingleError(ex, env) 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /spring-graphql-rsocket-kotlin-co/src/main/kotlin/com/example/demo/gql/PostsRuntimeWiring.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql 2 | 3 | import com.example.demo.Scalars 4 | import com.example.demo.gql.directives.UpperCaseDirectiveWiring 5 | import graphql.schema.idl.RuntimeWiring 6 | import org.springframework.graphql.execution.RuntimeWiringConfigurer 7 | import org.springframework.stereotype.Component 8 | 9 | @Component 10 | class PostsRuntimeWiring : RuntimeWiringConfigurer { 11 | override fun configure(builder: RuntimeWiring.Builder) { 12 | builder 13 | .scalar(Scalars.uuidType()) 14 | .scalar(Scalars.localDateTimeType()) 15 | .directive("uppercase", UpperCaseDirectiveWiring()) 16 | .build() 17 | } 18 | } -------------------------------------------------------------------------------- /spring-graphql-rsocket-kotlin-co/src/main/kotlin/com/example/demo/gql/directives/UpperCaseDirectiveWiring.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.directives 2 | 3 | import graphql.schema.DataFetcherFactories 4 | import graphql.schema.GraphQLFieldDefinition 5 | import graphql.schema.idl.SchemaDirectiveWiring 6 | import graphql.schema.idl.SchemaDirectiveWiringEnvironment 7 | import java.util.* 8 | 9 | class UpperCaseDirectiveWiring : SchemaDirectiveWiring { 10 | override fun onField(env: SchemaDirectiveWiringEnvironment): GraphQLFieldDefinition { 11 | 12 | val field = env.element; 13 | val dataFetcher = DataFetcherFactories 14 | .wrapDataFetcher( 15 | env.fieldDataFetcher 16 | ) { _, value -> if (value is String && value.isNotEmpty()) value.uppercase(Locale.getDefault()) else value } 17 | 18 | env.fieldDataFetcher = dataFetcher; 19 | return field 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /spring-graphql-rsocket-kotlin-co/src/main/kotlin/com/example/demo/gql/scalars/Scalars.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo 2 | 3 | import com.example.demo.gql.scalars.LocalDateTimeScalar 4 | import com.example.demo.gql.scalars.UUIDScalar 5 | import graphql.schema.* 6 | 7 | 8 | object Scalars { 9 | fun uuidType(): GraphQLScalarType { 10 | return GraphQLScalarType.newScalar() 11 | .name("UUID") 12 | .description("UUID type") 13 | .coercing(UUIDScalar()) 14 | .build() 15 | } 16 | 17 | fun localDateTimeType(): GraphQLScalarType { 18 | return GraphQLScalarType.newScalar() 19 | .name("LocalDateTime") 20 | .description("LocalDateTime type") 21 | .coercing(LocalDateTimeScalar()) 22 | .build() 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /spring-graphql-rsocket-kotlin-co/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.root=INFO 2 | logging.level.web=TRACE 3 | logging.level.org.springframework.messaging.rsocket.RSocketRequester=TRACE 4 | logging.level.org.springframework.graphql=TRACE 5 | logging.level.sql=DEBUG 6 | logging.level.com.example=DEBUG 7 | 8 | spring.r2dbc.url=r2dbc:postgresql://localhost/blogdb 9 | spring.r2dbc.username=user 10 | spring.r2dbc.password=password 11 | spring.sql.init.mode=always 12 | 13 | spring.rsocket.server.port=7000 14 | spring.rsocket.server.transport=tcp 15 | spring.graphql.rsocket.mapping=graphql 16 | spring.graphql.schema.printer.enabled=true 17 | -------------------------------------------------------------------------------- /spring-graphql-webflux/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/spring-graphql-webflux/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /spring-graphql-webflux/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /spring-graphql-webflux/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://repo.spring.io/milestone' } 4 | gradlePluginPortal() 5 | } 6 | } 7 | rootProject.name = 'spring-graphql-webflux' 8 | -------------------------------------------------------------------------------- /spring-graphql-webflux/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-graphql-webflux/src/main/java/com/example/demo/gql/types/Author.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | import lombok.ToString; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | @Data 11 | @Builder 12 | @ToString 13 | public class Author { 14 | String id; 15 | String name; 16 | String email; 17 | @Builder.Default 18 | List posts = new ArrayList<>(); 19 | } 20 | -------------------------------------------------------------------------------- /spring-graphql-webflux/src/main/java/com/example/demo/gql/types/Comment.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.*; 4 | 5 | @Data 6 | @Builder 7 | @ToString 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class Comment { 11 | String id; 12 | String postId; 13 | String content; 14 | } 15 | -------------------------------------------------------------------------------- /spring-graphql-webflux/src/main/java/com/example/demo/gql/types/CommentInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.*; 4 | import org.hibernate.validator.constraints.Length; 5 | 6 | import jakarta.validation.constraints.NotEmpty; 7 | 8 | @Getter 9 | @Setter 10 | @ToString 11 | @Builder 12 | @AllArgsConstructor 13 | @RequiredArgsConstructor 14 | public class CommentInput { 15 | @NotEmpty 16 | @Length(min = 5, max = 250) 17 | String content; 18 | 19 | @NotEmpty 20 | String postId; 21 | } 22 | -------------------------------------------------------------------------------- /spring-graphql-webflux/src/main/java/com/example/demo/gql/types/CreatePostInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.*; 4 | import org.hibernate.validator.constraints.Length; 5 | 6 | import jakarta.validation.constraints.NotEmpty; 7 | 8 | @Getter 9 | @Setter 10 | @ToString 11 | @RequiredArgsConstructor 12 | public class CreatePostInput { 13 | @NotEmpty 14 | @Length(min = 5, max = 100) 15 | String title; 16 | 17 | @NotEmpty 18 | @Length(min = 5, max = 1000) 19 | String content; 20 | } 21 | -------------------------------------------------------------------------------- /spring-graphql-webflux/src/main/java/com/example/demo/gql/types/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.*; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | @Data 9 | @Builder 10 | @ToString 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | public class Post { 14 | String id; 15 | String title; 16 | String content; 17 | 18 | @Builder.Default 19 | List comments = new ArrayList<>(); 20 | String authorId; 21 | Author author; 22 | } 23 | -------------------------------------------------------------------------------- /spring-graphql-webflux/src/main/java/com/example/demo/model/AuthorEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record AuthorEntity( 7 | UUID id, 8 | String name, 9 | String email, 10 | LocalDateTime createdAt 11 | ) { 12 | } 13 | 14 | -------------------------------------------------------------------------------- /spring-graphql-webflux/src/main/java/com/example/demo/model/CommentEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record CommentEntity( 7 | UUID id, 8 | String content, 9 | LocalDateTime createdAt, 10 | UUID postId 11 | ) { 12 | } 13 | -------------------------------------------------------------------------------- /spring-graphql-webflux/src/main/java/com/example/demo/model/PostEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record PostEntity( 7 | UUID id, 8 | String title, 9 | String content, 10 | String status, 11 | LocalDateTime createdAt, 12 | UUID authorId 13 | ) { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /spring-graphql-webflux/src/main/java/com/example/demo/service/AuthorNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class AuthorNotFoundException extends RuntimeException { 4 | public AuthorNotFoundException(String id) { 5 | super("Author: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /spring-graphql-webflux/src/main/java/com/example/demo/service/PostNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class PostNotFoundException extends RuntimeException { 4 | public PostNotFoundException(String id) { 5 | super("Post: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /spring-graphql-webflux/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.r2dbc.url=r2dbc:postgresql://localhost/blogdb 2 | spring.r2dbc.username=user 3 | spring.r2dbc.password=password 4 | spring.sql.init.mode=always 5 | 6 | # enable WebSocket transport protocol 7 | spring.graphql.websocket.path=/ws/graphql 8 | spring.graphql.schema.printer.enabled=true 9 | 10 | logging.level.root=INFO 11 | logging.level.sql=DEBUG 12 | logging.level.web=DEBUG 13 | logging.level.com.example=DEBUG 14 | logging.level.graphql=DEBUG 15 | logging.level.org.springframework.graphql=DEBUG -------------------------------------------------------------------------------- /spring-graphql-webflux/src/main/resources/graphql/schema.graphqls: -------------------------------------------------------------------------------- 1 | type Post{ 2 | id: ID! 3 | title: String! 4 | content: String 5 | comments: [Comment] 6 | authorId:String 7 | author:Author 8 | } 9 | type Author{ 10 | id:ID! 11 | name:String! 12 | email:String! 13 | posts: [Post] 14 | } 15 | type Comment{ 16 | id: ID! 17 | content: String! 18 | postId: String! 19 | } 20 | 21 | input CreatePostInput { 22 | title: String! 23 | content: String! 24 | } 25 | 26 | input CommentInput{ 27 | postId: String! 28 | content: String! 29 | } 30 | 31 | type Query{ 32 | allPosts: [Post!]! 33 | postById(postId: String!): Post 34 | } 35 | 36 | type Mutation{ 37 | createPost(createPostInput: CreatePostInput!): Post! 38 | addComment(commentInput: CommentInput!): Comment! 39 | } 40 | 41 | type Subscription{ 42 | commentAdded: Comment! 43 | } -------------------------------------------------------------------------------- /spring-graphql-webmvc/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/spring-graphql-webmvc/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /spring-graphql-webmvc/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://repo.spring.io/milestone' } 4 | gradlePluginPortal() 5 | } 6 | } 7 | rootProject.name = 'spring-graphql-webmvc-example' 8 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/main/java/com/example/demo/gql/types/Author.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class Author { 17 | 18 | private String id; 19 | 20 | private String name; 21 | 22 | private String email; 23 | 24 | private LocalDateTime createdAt; 25 | 26 | @Builder.Default 27 | private List posts = new ArrayList<>(); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/main/java/com/example/demo/gql/types/Comment.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | 10 | @Data 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class Comment { 15 | 16 | private String id; 17 | 18 | private String content; 19 | 20 | private LocalDateTime createdAt; 21 | 22 | private String postId; 23 | } 24 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/main/java/com/example/demo/gql/types/CommentInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import jakarta.validation.constraints.NotBlank; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @Builder 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class CommentInput { 14 | private String postId; 15 | 16 | @NotBlank 17 | private String content; 18 | } 19 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/main/java/com/example/demo/gql/types/CreatePostInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import jakarta.validation.constraints.NotBlank; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | import jakarta.validation.constraints.NotEmpty; 10 | import jakarta.validation.constraints.Size; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor() 16 | public class CreatePostInput { 17 | 18 | @NotBlank 19 | @Size(min = 5, max = 100) 20 | private String title; 21 | 22 | @NotBlank 23 | private String content; 24 | } 25 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/main/java/com/example/demo/gql/types/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class Post { 17 | private String id; 18 | private String title; 19 | private String content; 20 | 21 | @Builder.Default 22 | private List comments = new ArrayList<>(); 23 | private PostStatus status; 24 | private LocalDateTime createdAt; 25 | 26 | private String authorId; 27 | private Author author; 28 | } 29 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/main/java/com/example/demo/gql/types/PostStatus.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | public enum PostStatus { 4 | DRAFT, 5 | PENDING_MODERATION, 6 | PUBLISHED 7 | } 8 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/main/java/com/example/demo/model/AuthorEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record AuthorEntity( 7 | UUID id, 8 | String name, 9 | String email, 10 | LocalDateTime createdAt 11 | ) { 12 | } 13 | 14 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/main/java/com/example/demo/model/CommentEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record CommentEntity( 7 | UUID id, 8 | String content, 9 | LocalDateTime createdAt, 10 | UUID postId 11 | ) { 12 | } 13 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/main/java/com/example/demo/model/PostEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record PostEntity( 7 | UUID id, 8 | String title, 9 | String content, 10 | String status, 11 | LocalDateTime createdAt, 12 | UUID authorId 13 | ) { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/main/java/com/example/demo/service/AuthorNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class AuthorNotFoundException extends RuntimeException { 4 | public AuthorNotFoundException(String id) { 5 | super("Author: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/main/java/com/example/demo/service/PostNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class PostNotFoundException extends RuntimeException { 4 | public PostNotFoundException(String id) { 5 | super("Post: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:postgresql://localhost/blogdb 2 | spring.datasource.username=user 3 | spring.datasource.password=password 4 | spring.sql.init.mode=always 5 | 6 | spring.graphql.websocket.path=/subscriptions 7 | #spring.graphql.schema.locations= 8 | # 9 | # Logging level 10 | # 11 | logging.level.root=INFO 12 | logging.level.com.example=DEBUG 13 | logging.level.web=DEBUG 14 | logging.level.sql=DEBUG 15 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/main/resources/graphql/schema.graphqls: -------------------------------------------------------------------------------- 1 | type Post{ 2 | id: ID! 3 | title: String! 4 | content: String 5 | comments: [Comment] 6 | status: PostStatus 7 | authorId:String 8 | author:Author 9 | } 10 | 11 | type Author{ 12 | id:ID! 13 | name:String! 14 | email:String! 15 | posts: [Post] 16 | } 17 | type Comment{ 18 | id: ID! 19 | content: String! 20 | postId: String! 21 | } 22 | 23 | input CreatePostInput { 24 | title: String! 25 | content: String! 26 | } 27 | 28 | input CommentInput{ 29 | postId: String! 30 | content: String! 31 | } 32 | 33 | type Query { 34 | allPosts: [Post!]! 35 | postById(postId: String!): Post 36 | } 37 | 38 | type Mutation { 39 | createPost(createPostInput: CreatePostInput!): Post! 40 | # upload(file: Upload!): Boolean! 41 | addComment(commentInput: CommentInput!): Comment! 42 | } 43 | 44 | type Subscription { 45 | commentAdded: Comment! 46 | } 47 | enum PostStatus { 48 | DRAFT, PENDING_MODERATION, PUBLISHED 49 | } 50 | 51 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/test/java/com/example/demo/TestDemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.test.context.TestConfiguration; 6 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 7 | import org.springframework.context.annotation.Bean; 8 | import org.testcontainers.containers.PostgreSQLContainer; 9 | import org.testcontainers.utility.MountableFile; 10 | 11 | @TestConfiguration 12 | public class TestDemoApplication { 13 | 14 | @Bean 15 | @ServiceConnection 16 | PostgreSQLContainer postgreSQLContainer() { 17 | return new PostgreSQLContainer<>("postgres:14") 18 | .withCopyFileToContainer(MountableFile.forClasspathResource("init.sql"), "/docker-entrypoint-initdb.d/init.sql"); 19 | } 20 | 21 | public static void main(String[] args) { 22 | SpringApplication.from(DemoApplication::main) 23 | .with(TestDemoApplication.class) 24 | .run(args); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /spring-graphql-webmvc/src/test/resources/init.sql: -------------------------------------------------------------------------------- 1 | CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; 2 | -------------------------------------------------------------------------------- /spring-graphql/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /spring-graphql/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hantsy/spring-graphql-sample/35924bdb91e11e1658361ad40cd3634f4f671f8b/spring-graphql/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /spring-graphql/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /spring-graphql/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://repo.spring.io/milestone' } 4 | gradlePluginPortal() 5 | } 6 | } 7 | rootProject.name = 'spring-graphql-example' 8 | -------------------------------------------------------------------------------- /spring-graphql/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-graphql/src/main/java/com/example/demo/gql/scalars/Scalars.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.scalars; 2 | 3 | import graphql.schema.GraphQLScalarType; 4 | 5 | public class Scalars { 6 | 7 | public static GraphQLScalarType uuidType() { 8 | return GraphQLScalarType.newScalar() 9 | .name("UUID") 10 | .description("UUID type") 11 | .coercing(new UUIDScalar()) 12 | .build(); 13 | } 14 | 15 | public static GraphQLScalarType localDateTimeType() { 16 | return GraphQLScalarType.newScalar() 17 | .name("LocalDateTime") 18 | .description("LocalDateTime type") 19 | .coercing(new LocalDateTimeScalar()) 20 | .build(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /spring-graphql/src/main/java/com/example/demo/gql/types/Author.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class Author { 17 | 18 | private String id; 19 | 20 | private String name; 21 | 22 | private String email; 23 | 24 | private LocalDateTime createdAt; 25 | 26 | @Builder.Default 27 | private List posts = new ArrayList<>(); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /spring-graphql/src/main/java/com/example/demo/gql/types/Comment.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | 10 | @Data 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class Comment { 15 | 16 | private String id; 17 | 18 | private String content; 19 | 20 | private LocalDateTime createdAt; 21 | 22 | private String postId; 23 | } 24 | -------------------------------------------------------------------------------- /spring-graphql/src/main/java/com/example/demo/gql/types/CommentInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @Builder 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class CommentInput { 13 | private String postId; 14 | private String content; 15 | } 16 | -------------------------------------------------------------------------------- /spring-graphql/src/main/java/com/example/demo/gql/types/CreatePostInput.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @Builder 10 | @NoArgsConstructor 11 | @AllArgsConstructor() 12 | public class CreatePostInput { 13 | 14 | private String title; 15 | 16 | private String content; 17 | } 18 | -------------------------------------------------------------------------------- /spring-graphql/src/main/java/com/example/demo/gql/types/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDateTime; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class Post { 17 | private String id; 18 | private String title; 19 | private String content; 20 | 21 | @Builder.Default 22 | private List comments = new ArrayList<>(); 23 | private PostStatus status; 24 | private LocalDateTime createdAt; 25 | 26 | private String authorId; 27 | private Author author; 28 | } 29 | -------------------------------------------------------------------------------- /spring-graphql/src/main/java/com/example/demo/gql/types/PostStatus.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.gql.types; 2 | 3 | public enum PostStatus { 4 | DRAFT, 5 | PENDING_MODERATION, 6 | PUBLISHED 7 | } 8 | -------------------------------------------------------------------------------- /spring-graphql/src/main/java/com/example/demo/model/AuthorEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record AuthorEntity( 7 | UUID id, 8 | String name, 9 | String email, 10 | LocalDateTime createdAt 11 | ) { 12 | } 13 | 14 | -------------------------------------------------------------------------------- /spring-graphql/src/main/java/com/example/demo/model/CommentEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record CommentEntity( 7 | UUID id, 8 | String content, 9 | LocalDateTime createdAt, 10 | UUID postId 11 | ) { 12 | } 13 | -------------------------------------------------------------------------------- /spring-graphql/src/main/java/com/example/demo/model/PostEntity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record PostEntity( 7 | UUID id, 8 | String title, 9 | String content, 10 | String status, 11 | LocalDateTime createdAt, 12 | UUID authorId 13 | ) { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /spring-graphql/src/main/java/com/example/demo/service/AuthorNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class AuthorNotFoundException extends RuntimeException { 4 | public AuthorNotFoundException(String id) { 5 | super("Author: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /spring-graphql/src/main/java/com/example/demo/service/PostNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | public class PostNotFoundException extends RuntimeException { 4 | public PostNotFoundException(String id) { 5 | super("Post: " + id + " was not found."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /spring-graphql/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:postgresql://localhost/blogdb 2 | spring.datasource.username=user 3 | spring.datasource.password=password 4 | spring.sql.init.mode=always 5 | #spring.graphql.schema.locations= 6 | # 7 | # Logging level 8 | # 9 | logging.level.com.example=DEBUG 10 | logging.level.sql=DEBUG 11 | logging.level.web=DEBUG 12 | logging.level.root=INFO 13 | -------------------------------------------------------------------------------- /spring-graphql/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | DELETE FROM posts; 2 | DELETE FROM users; --------------------------------------------------------------------------------