Skip to content

Commit

Permalink
Source generator samples (#1636)
Browse files Browse the repository at this point in the history
  • Loading branch information
pekkah authored Apr 25, 2023
1 parent f1a62f3 commit da8efbb
Show file tree
Hide file tree
Showing 64 changed files with 1,653 additions and 379 deletions.
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

0 comments on commit da8efbb

Please sign in to comment.