Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Source generator samples #1636

Merged
merged 2 commits into from
Apr 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ Install package
dotnet add Tanka.GraphQL.Server.SourceGenerators
```

### Tanka.GraphQL.Samples.SourceGenerators
### Tanka.GraphQL.Samples.SG.Basic

```csharp
#include::xref://samples:GraphQL.Samples.SourceGenerators/Program.cs
#include::xref://samples:GraphQL.Samples.SG.Basic/Program.cs
```

19 changes: 19 additions & 0 deletions docs/4-code-generator/02-samples-sg-arguments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
## Arguments

Code generator will extract the arguments from the resolver and generate calls
to bind the arguments from the resolver context. It will also generate the
correct field definition for the field. Arguments can be primitive types or
input object types.

### Tanka.GraphQL.Samples.SG.Arguments

```csharp
#include::xref://samples:GraphQL.Samples.SG.Arguments/Program.cs
```

### Tanka.GraphQL.Samples.SG.InputType

```csharp
#include::xref://samples:GraphQL.Samples.SG.InputType/Program.cs
```

16 changes: 16 additions & 0 deletions docs/4-code-generator/03-samples-sg-namespace.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## Namespaces

When generating code the generator will place the generates
types into same namespace as the annotated classes.

> WARN: Using of namespaces is supported in C# but the generated
> types can conflict in the SDL when their names are the same.

Generator will generate a namespace specific add method to add
all types from the namespace to the schema.

### Tanka.GraphQL.Samples.SG.Namespace

```csharp
#include::xref://samples:GraphQL.Samples.SG.Namespace/Program.cs
```
14 changes: 14 additions & 0 deletions docs/4-code-generator/04-samples-sg-services.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## Services

Generator supports injecting services into the generated resolvers.

By default the generated code will first check the field arguments for
the argument and then fallback to the DI. It's recommended to use
[FromServices] attribute to make the intent clear and simplify the generated
code.

### Tanka.GraphQL.Samples.SG.Services

```csharp
#include::xref://samples:GraphQL.Samples.SG.Services/Program.cs
```
5 changes: 4 additions & 1 deletion docs/4-code-generator/nav.md
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
- [Installation](xref://1-samples-basic.md)
- [Installation & basics](xref://01-samples-sg-basic.md)
- [Arguments](xref://02-samples-sg-arguments.md)
- [Namespace](xref://03-samples-sg-namespace.md)
- [Dependency injection](xref://04-samples-sg-services.md)
2 changes: 1 addition & 1 deletion docs/4-code-generator/tanka-docs-section.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
id: codegen
title: "Code Generation"
index_page: xref://codegen:1-samples-basic.md
index_page: xref://codegen:01-samples-sg-basic.md
nav:
- xref://nav.md
2 changes: 1 addition & 1 deletion samples/GraphQL.Samples.Authorization/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ static async IAsyncEnumerable<string> Hello(

builder.Services.AddAuthorization();

WebApplication? app = builder.Build();
WebApplication app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();
Expand Down
2 changes: 1 addition & 1 deletion samples/GraphQL.Samples.Http/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
});
});

WebApplication? app = builder.Build();
WebApplication app = builder.Build();

// this is required by the websocket transport
app.UseWebSockets();
Expand Down
61 changes: 61 additions & 0 deletions samples/GraphQL.Samples.SG.Arguments/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Tanka.GraphQL.Server;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

// Add tanka graphql
builder.AddTankaGraphQL()
.AddHttp()
.AddWebSockets()
.AddSchemaOptions("Default", options =>
{
options.AddGeneratedTypes(types =>
{
// add object type controllers from <global> namespace
types.AddGlobalControllers();

// Add generated input type to schema
//todo: make a namespace add all method for this
types.AddQueryOptionsInputType();
});
});

WebApplication app = builder.Build();
app.UseWebSockets();

app.MapTankaGraphQL("/graphql", "Default");
app.Run();


[ObjectType]
public static class Query
{
/// <summary>
/// Resolver with two primitive arguments
/// </summary>
/// <param name="start">Bound automatically from args</param>
/// <param name="count">Bound automatically from args</param>
/// <returns></returns>
public static int[] Range(int start, int count)
{
return Enumerable.Range(start, count).ToArray();
}

/// <summary>
/// Resolver with input object argument
/// </summary>
/// <param name="options">todo: bug - requires [FromArguments] in combination with [InputObject]</param>
/// <returns></returns>
public static int[] RangeWithInputObject([FromArguments]QueryOptions options)
{
return Enumerable.Range(options.Start, options.Count).ToArray();
}
}


[InputType]
public class QueryOptions
{
public int Start { get; set; } = 0;

public int Count { get; set; } = 100;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"profiles": {
"GraphQL.Samples.SourceGenerators": {
"GraphQL.Samples.SG.Arguments": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "https://localhost:7239/graphql/ui",
Expand Down
19 changes: 19 additions & 0 deletions samples/GraphQL.Samples.SG.Basic/GraphQL.Samples.SG.Basic.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\GraphQL.Language\GraphQL.Language.csproj" />
<ProjectReference Include="..\..\src\GraphQL.Server\GraphQL.Server.csproj" />
<ProjectReference Include="..\..\src\GraphQL\GraphQL.csproj" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\GraphQL.Server.SourceGenerators\GraphQL.Server.SourceGenerators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,14 @@
// type controllers
options.AddGeneratedTypes(types =>
{
// This method is generated by the generator from Query class
types.AddQueryController();

// This method is generated by the generator from World class
types.AddWorldController();

//todo: generate namespace specific method for adding all types in namespace
// Add generated controllers
types
.AddWorldController()
.AddQueryController();
});
});

WebApplication? app = builder.Build();
WebApplication app = builder.Build();
app.UseWebSockets();

app.MapTankaGraphQL("/graphql", "Default");
Expand Down
14 changes: 14 additions & 0 deletions samples/GraphQL.Samples.SG.Basic/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"profiles": {
"GraphQL.Samples.SG.Basic": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "https://localhost:7239/graphql/ui",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:7239",
"dotnetRunMessages": true
}
}
}
8 changes: 8 additions & 0 deletions samples/GraphQL.Samples.SG.Basic/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
9 changes: 9 additions & 0 deletions samples/GraphQL.Samples.SG.Basic/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\GraphQL.Language\GraphQL.Language.csproj" />
<ProjectReference Include="..\..\src\GraphQL.Server\GraphQL.Server.csproj" />
<ProjectReference Include="..\..\src\GraphQL\GraphQL.csproj" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\GraphQL.Server.SourceGenerators\GraphQL.Server.SourceGenerators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>

</Project>
93 changes: 93 additions & 0 deletions samples/GraphQL.Samples.SG.InputType/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System.Collections.Concurrent;
using Microsoft.AspNetCore.Mvc;
using Tanka.GraphQL.Server;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

// Simple in memory db for messages
builder.Services.AddSingleton<Db>();

// Add tanka graphql
builder.AddTankaGraphQL()
.AddHttp()
.AddWebSockets()
.AddSchemaOptions("Default", options =>
{
options.AddGeneratedTypes(types =>
{
// add object type controllers from <global> namespace
types.AddGlobalControllers();

// Add generated input type to schema
//todo: make a namespace add all method for this
types.AddInputMessageInputType();
});
});

WebApplication app = builder.Build();
app.UseWebSockets();

app.MapTankaGraphQL("/graphql", "Default");
app.Run();


[ObjectType]
public static class Query
{
/// <summary>
/// Simple query with one dependency resolved from DI
/// </summary>
/// <remarks>
/// [FromServices] is provided by Microsoft.AspNetCore.Mvc
/// </remarks>
/// <param name="db"></param>
/// <returns></returns>
public static Message[] Messages([FromServices]Db db)
{
return db.Messages.ToArray();
}
}

[ObjectType]
public static class Mutation
{
/// <summary>
/// Simple mutation with one InputObject argument and one dependency resolved from DI
/// </summary>
/// <remarks>
/// [FromArguments} is provided by Tanka.GraphQL.Server
/// </remarks>
/// <param name="input"></param>
/// <param name="db"></param>
/// <returns></returns>
public static Message Post([FromArguments]InputMessage input, [FromServices]Db db)
{
var message = new Message
{
Id = Guid.NewGuid().ToString(),
Text = input.Text
};

db.Messages.Add(message);
return message;
}
}

[ObjectType]
public class Message
{
public required string Id { get; set; }

public required string Text { get; set; }
}

[InputType]
public class InputMessage
{
public string Text { get; set; } = string.Empty;
}

public class Db
{
public ConcurrentBag<Message> Messages { get; } = new();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"profiles": {
"GraphQL.Samples.SG.InputType": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "https://localhost:7239/graphql/ui",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:7239",
"dotnetRunMessages": true
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
9 changes: 9 additions & 0 deletions samples/GraphQL.Samples.SG.InputType/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Loading