Building GraphQL Server on ASP.NET Core
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
GET /posts | |
GET /posts/{postId} | |
GET /authors | |
GET /authors/{authorId} | |
GET /tags | |
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dotnet new classlib -n PostsQL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dotnet add package GraphQL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Author | |
{ | |
public Author(int id, string name) | |
{ | |
this.Id = id; | |
this.Name = name; | |
} | |
public int Id { get; set; } | |
public string Name { get; set; } | |
} | |
public class Post | |
{ | |
public Post(int id, string title, string slug, DateTimeOffset published, string authorId, PostStatus status) | |
{ | |
this.Id = id; | |
this.Title = title; | |
this.Slug = slug; | |
this.Published = published; | |
this.AuthorId = authorId; | |
this.Status = status; | |
} | |
public int Id { get; set; } | |
public string Title { get; set; } | |
public string Slug { get; set; } | |
public DateTimeOffset Published { get; set; } | |
public string AuthorId { get; set; } | |
public PostStatus Status { get; set; } | |
} | |
public enum PostStatus | |
{ | |
Created = 1, | |
Published = 2, | |
Deleted = 3 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface IAuthorService | |
{ | |
Task<Author> GetAuthorByIdAsync(int id); | |
Task<List<Author>> GetAuthorsAsync(); | |
} | |
public class AuthorService : IAuthorService | |
{ | |
private readonly List<Author> _authors; | |
public AuthorService() | |
{ | |
this._authors = new List<Author>() | |
{ | |
new Author(1, "Natasha Romanoff"), | |
new Author(2, "Carol Danvers"), | |
new Author(3, "Jean Grey"), | |
new Author(4, "Wanda Maximoff"), | |
new Author(5, "Gamora"), | |
}; | |
} | |
public async Task<Author> GetAuthorByIdAsync(int id) | |
{ | |
return await Task.FromResult(this._authors.SingleOrDefault(p => p.Id.Equals(id))); | |
} | |
public async Task<List<Author>> GetAuthorsAsync() | |
{ | |
return await Task.FromResult(this._authors); | |
} | |
} | |
public interface IPostService | |
{ | |
Task<Post> GetPostByIdAsync(int id); | |
Task<List<Post>> GetPostsAsync(); | |
} | |
public class PostService | |
{ | |
private readonly List<Post> _posts; | |
public PostService() | |
{ | |
this._posts = new List<Post>() | |
{ | |
new Post(1, "Post #1", "post-1", DateTimeOffset.UtcNow.AddHours(-4), 1, PostStatus.Deleted), | |
new Post(2, "Post #2", "post-2", DateTimeOffset.UtcNow.AddHours(-3), 2, PostStatus.Published), | |
new Post(3, "Post #3", "post-3", DateTimeOffset.UtcNow.AddHours(-2), 3, PostStatus.Published), | |
new Post(4, "Post #4", "post-4", DateTimeOffset.UtcNow.AddHours(-1), 4, PostStatus.Published), | |
new Post(5, "Post #5", "post-5", DateTimeOffset.UtcNow.AddHours(0), 5, PostStatus.Created), | |
}; | |
} | |
public async Task<Post> GetPostByIdAsync(int id) | |
{ | |
return await Task.FromResult(this._posts.SingleOrDefault(p => p.Id.Equals(id))); | |
} | |
public async Task<List<Post>> GetPostsAsync() | |
{ | |
return await Task.FromResult(this._posts); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class AuthorType : ObjectGraphType<Author> | |
{ | |
public AuthorType() | |
{ | |
this.Field(p => p.Id); | |
this.Field(p => p.Name); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PostStatusEnum : EnumerationGraphType | |
{ | |
public PostStatusEnum() | |
{ | |
this.Name = "PostStatus"; | |
this.AddValue(new EnumValueDefinition() { Name = "Created", Description = "Post was created", Value = 1 }); | |
this.AddValue(new EnumValueDefinition() { Name = "Published", Description = "Post has been published", Value = 2 }); | |
this.AddValue(new EnumValueDefinition() { Name = "Deleted", Description = "Post was deleted", Value = 3 }); | |
} | |
} | |
public class PostType : ObjectGraphType<Post> | |
{ | |
private readonly IAuthorService _authorService; | |
public PostType(IAuthorService authorService) | |
{ | |
this._authorService = authorService; | |
this.Field(p => p.Id); | |
this.Field(p => p.Title); | |
this.Field(p => p.Slug); | |
this.Field(p => p.Published); | |
this.FieldAsync<AuthorType>("author", resolve: async c => await this._authorService.GetAuthorByIdAsync(c.Source.AuthorId)); | |
this.Field<PostStatusEnum>("status", resolve: c => c.Source.Status); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PostsQuery : ObjectGraphType<object> | |
{ | |
private readonly IPostService _postService; | |
public PostsQuery(IPostService postService) | |
{ | |
this._postService = postService; | |
this.Name = "Query"; | |
this.FieldAsync<ListGraphType<PostType>>( | |
"posts", | |
resolve: async c => await this._postService.GetPostsAsync()); | |
this.FieldAsync<PostType>( | |
"post", | |
arguments: new QueryArguments( | |
new QueryArgument<NonNullGraphType<IntGraphType>>() { Name = "id", Description = "Post ID" }), | |
resolve: async c => await this._postService.GetPostByIdAsync(c.GetArgument<int>("id"))); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PostsSchema : Schema | |
{ | |
public PostsSchema(PostsQuery query, IDependencyResolver resolver) | |
{ | |
this.Query = query; | |
this.DependencyResolver = resolver; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dotnet new web -n Server.WebApp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dotnet add package Microsoft.AspNetCore | |
dotnet add package GraphQL.Server.Core | |
dotnet add package GraphQL.Server.Transports.AspNetCore | |
dotnet add package GraphQL.Server.Transports.WebSockets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dotnet add package GraphQL-Parser -v 4.1.2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dotnet add package GraphQL.Server.Ui.GraphiQL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dotnet add reference PostsQL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Startup | |
{ | |
public void ConfigureServices(IServiceCollection services) | |
{ | |
services.AddSingleton<IAuthorService, AuthorService>(); | |
services.AddSingleton<IPostService, PostService>(); | |
services.AddSingleton<AuthorType>(); | |
services.AddSingleton<PostType>(); | |
services.AddSingleton<PostStatusEnum>(); | |
services.AddSingleton<PostsQuery>(); | |
services.AddSingleton<PostsSchema>(); | |
services.AddSingleton<IDependencyResolver>(p => new FuncDependencyResolver(type => p.GetRequiredService(type))); | |
services.AddGraphQL() | |
.AddWebSockets() | |
.AddGraphTypes(Assembly.GetAssembly(typeof(PostsSchema))); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Startup | |
{ | |
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | |
{ | |
... | |
app.UseEndpoints(endpoints => | |
{ | |
endpoints.MapGet("/", async context => | |
{ | |
await Task.Run(() => context.Response.Redirect("/ui/graphql", permanent: true)); | |
}); | |
}); | |
app.UseWebSockets(); | |
app.UseGraphQLWebSockets<PostsSchema>(); | |
app.UseGraphQL<PostsSchema>(); | |
app.UseGraphiQLServer(new GraphiQLOptions() { GraphiQLPath = "/ui/graphql", GraphQLEndPoint = "/graphql" }); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dotnet run Server.WebApp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
https://localhost:5001/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public void ConfigureServices(IServiceCollection services) | |
{ | |
services.Configure<KestrelServerOptions>(o => o.AllowSynchronousIO = true); | |
... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
query { | |
post(id: 3) { | |
id, | |
title, | |
slug, | |
author { | |
id, | |
name | |
} | |
} | |
posts { | |
id, | |
title, | |
published | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"query": "query { post(id: 3) { id, title, slug, author { id, name } } posts { id, title, published } }", | |
"variables": null | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment