Skip to content

Commit b5dfa69

Browse files
authored
Merge pull request graphql-dotnet#362 from graphql-dotnet/instance
Initial work for supporting a schema builder
2 parents ded31b4 + 2b142b0 commit b5dfa69

File tree

62 files changed

+2170
-289
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+2170
-289
lines changed

README.md

Lines changed: 90 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -38,86 +38,103 @@ Define your schema with a top level query object then execute that query.
3838

3939
A more full-featured example including all classes required can be found [here](https://github.com/graphql-dotnet/graphql-dotnet/tree/master/src/GraphQL.StarWars).
4040

41+
### Hello World
42+
4143
```csharp
42-
namespace ConsoleApplication
44+
var schema = Schema.For(@"
45+
type Query {
46+
hello: String
47+
}
48+
");
49+
50+
var root = new { Hello = "Hello World!" };
51+
var result = schema.Execute(_ =>
4352
{
44-
using System;
45-
using System.Threading.Tasks;
46-
using GraphQL;
47-
using GraphQL.Http;
48-
using GraphQL.Types;
49-
50-
public class Program
51-
{
52-
public static void Main(string[] args)
53-
{
54-
Run();
55-
}
56-
57-
private static async void Run()
58-
{
59-
Console.WriteLine("Hello GraphQL!");
60-
61-
var schema = new Schema { Query = new StarWarsQuery() };
62-
63-
var result = await new DocumentExecuter().ExecuteAsync( _ =>
64-
{
65-
_.Schema = schema;
66-
_.Query = @"
67-
query {
68-
hero {
69-
id
70-
name
71-
}
72-
}
73-
";
74-
}).ConfigureAwait(false);
75-
76-
var json = new DocumentWriter(indent: true).Write(result);
77-
78-
Console.WriteLine(json);
79-
}
80-
}
81-
82-
public class Droid
83-
{
84-
public string Id { get; set; }
85-
public string Name { get; set; }
86-
}
87-
88-
public class DroidType : ObjectGraphType<Droid>
89-
{
90-
public DroidType()
91-
{
92-
Field(x => x.Id).Description("The Id of the Droid.");
93-
Field(x => x.Name, nullable: true).Description("The name of the Droid.");
94-
}
95-
}
96-
97-
public class StarWarsQuery : ObjectGraphType
98-
{
99-
public StarWarsQuery()
100-
{
101-
Field<DroidType>(
102-
"hero",
103-
resolve: context => new Droid { Id = "1", Name = "R2-D2" }
104-
);
105-
}
106-
}
107-
}
53+
_.Query = "{ hello }";
54+
_.Root = root;
55+
});
56+
57+
Console.WriteLine(result);
10858
```
10959

110-
Output
60+
### Handler/Endpoints
61+
62+
```csharp
63+
public class Droid
64+
{
65+
public string Id { get; set; }
66+
public string Name { get; set; }
67+
}
68+
69+
public class Query
70+
{
71+
[GraphQLMetadata("hero")]
72+
public Droid GetHero()
73+
{
74+
return new Droid { Id = "123", Name = "R2-D2" };
75+
}
76+
}
77+
78+
var schema = Schema.For(@"
79+
type Droid {
80+
id: String
81+
name: String
82+
}
83+
84+
type Query {
85+
hero: Droid
86+
}
87+
", _ => {
88+
_.Types.Include<Query>();
89+
});
90+
91+
var result = schema.Execute(_ =>
92+
{
93+
_.Query = "{ hero { id name } }";
94+
});
11195
```
112-
Hello GraphQL!
96+
97+
### Parameters
98+
99+
```csharp
100+
public class Droid
101+
{
102+
public string Id { get; set; }
103+
public string Name { get; set; }
104+
}
105+
106+
public class Query
113107
{
114-
"data": {
115-
"hero": {
116-
"id": "1",
117-
"name": "R2-D2"
118-
}
108+
private List<Droid> _droids = new List<Droid>
109+
{
110+
new Droid { Id = "123", Name = "R2-D2" }
111+
};
112+
113+
[GraphQLMetadata("hero")]
114+
public Droid GetHero(string id)
115+
{
116+
return _droids.FirstOrDefault(x => x.Id == id);
119117
}
120118
}
119+
120+
var schema = Schema.For(@"
121+
type Droid {
122+
id: String
123+
name: String
124+
}
125+
126+
type Query {
127+
hero(id: String): Droid
128+
}
129+
", _ => {
130+
_.Types.Include<Query>();
131+
});
132+
133+
string id = "123";
134+
var result = schema.Execute(_ =>
135+
{
136+
_.Query = $"{{ hero(id: \"{id}\") {{ id name }} }}";
137+
});
121138
```
122139

123140
## Roadmap
@@ -204,7 +221,7 @@ publish nuget from MyGet
204221
### Running on .NET Core
205222
The GraphQL.GraphiQLCore project runs on `.NET Core 1.1`. You can run from Visual Studio Code or from the command line using `dotnet run`. When you run the project, you will see the GraphiQL editor open.
206223

207-
When using Visual Studio Code, open to the `./src/GraphQL.GraphiQLCore` folder. You will get a warning "Required assets to build and debug are missing from 'GraphQL.GraphiQLCore'. Add Them?". Choose `Yes`. This will add the necessary launch.json and tasks.json files.
224+
When using Visual Studio Code, open to the `./src/GraphQL.GraphiQLCore` folder. You will get a warning "Required assets to build and debug are missing from 'GraphQL.GraphiQLCore'. Add Them?". Choose `Yes`. This will add the necessary launch.json and tasks.json files.
208225

209226
### Running on OSX with mono
210227
To run this project on OSX with mono you will need to add some configuration. Make sure mono is installed and add the following to your bash configuration:
@@ -217,4 +234,3 @@ See the following for more details:
217234

218235
* [Building VS 2017 MSBuild csproj Projects with Mono on Linux](https://stackoverflow.com/questions/42747722/building-vs-2017-msbuild-csproj-projects-with-mono-on-linux)
219236
* [using .NET Framework as targets framework, the osx/unix build fails](https://github.com/dotnet/netcorecli-fsc/wiki/.NET-Core-SDK-rc4#using-net-framework-as-targets-framework-the-osxunix-build-fails)
220-

appveyor.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version: 0.17.3.{build}
1+
version: 2.0.0.{build}
22
pull_requests:
33
do_not_increment_build_number: true
44
skip_tags: true
@@ -36,3 +36,4 @@ deploy:
3636
branch:
3737
- master
3838
- dev
39+
- instance

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "graphql-dotnet",
3-
"version": "0.17.3",
3+
"version": "2.0.0",
44
"description": "GraphQL for .NET",
55
"main": "index.js",
66
"scripts": {

src/GraphQL.GraphiQL/Bootstrapper.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
using System.Web.Http.Dependencies;
2-
using GraphQL.Http;
1+
using GraphQL.Http;
32
using GraphQL.StarWars;
43
using GraphQL.StarWars.IoC;
54
using GraphQL.StarWars.Types;
6-
using GraphQL.Types;
75

86
namespace GraphQL.GraphiQL
97
{
108
public class Bootstrapper
119
{
12-
public IDependencyResolver Resolver()
10+
public System.Web.Http.Dependencies.IDependencyResolver Resolver()
1311
{
1412
var container = BuildContainer();
1513
var resolver = new SimpleContainerDependencyResolver(container);
@@ -29,7 +27,7 @@ private ISimpleContainer BuildContainer()
2927
container.Register<HumanInputType>();
3028
container.Register<DroidType>();
3129
container.Register<CharacterInterface>();
32-
container.Singleton(new StarWarsSchema(type => (GraphType) container.Get(type)));
30+
container.Singleton(new StarWarsSchema(new FuncDependencyResolver(type => container.Get(type))));
3331

3432
return container;
3533
}

src/GraphQL.GraphiQL/SimpleContainerDependencyResolver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace GraphQL.GraphiQL
88
{
9-
public class SimpleContainerDependencyResolver : IDependencyResolver
9+
public class SimpleContainerDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver
1010
{
1111
private readonly ISimpleContainer _container;
1212

src/GraphQL.GraphiQLCore/GraphQLMiddleware.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.IO;
43
using System.Linq;
54
using System.Net;
65
using System.Threading.Tasks;
76
using GraphQL.Http;
7+
using GraphQL.Types;
88
using Microsoft.AspNetCore.Http;
99
using Newtonsoft.Json;
1010

@@ -29,15 +29,15 @@ public GraphQLMiddleware(
2929
_writer = writer;
3030
}
3131

32-
public async Task Invoke(HttpContext context)
32+
public async Task Invoke(HttpContext context, ISchema schema)
3333
{
3434
if (!IsGraphQLRequest(context))
3535
{
36-
await _next(context).ConfigureAwait(false);
36+
await _next(context);
3737
return;
3838
}
3939

40-
await ExecuteAsync(context);
40+
await ExecuteAsync(context, schema);
4141
}
4242

4343
private bool IsGraphQLRequest(HttpContext context)
@@ -46,7 +46,7 @@ private bool IsGraphQLRequest(HttpContext context)
4646
&& string.Equals(context.Request.Method, "POST", StringComparison.OrdinalIgnoreCase);
4747
}
4848

49-
private async Task ExecuteAsync(HttpContext context)
49+
private async Task ExecuteAsync(HttpContext context, ISchema schema)
5050
{
5151
string body;
5252
using (var streamReader = new StreamReader(context.Request.Body))
@@ -58,10 +58,11 @@ private async Task ExecuteAsync(HttpContext context)
5858

5959
var result = await _executer.ExecuteAsync(_ =>
6060
{
61-
_.Schema = _settings.Schema;
61+
_.Schema = schema;
6262
_.Query = request.Query;
6363
_.OperationName = request.OperationName;
6464
_.Inputs = request.Variables.ToInputs();
65+
_.UserContext = _settings.BuildUserContext?.Invoke(context);
6566
});
6667

6768
await WriteResponseAsync(context, result);
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
using GraphQL.Types;
1+
using System;
22
using Microsoft.AspNetCore.Http;
33

44
namespace GraphQL.GraphiQLCore
55
{
66
public class GraphQLSettings
77
{
88
public PathString Path { get; set; } = "/api/graphql";
9-
public ISchema Schema { get; set; }
9+
public Func<HttpContext, object> BuildUserContext { get; set; }
1010
}
1111
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System.Security.Claims;
2+
3+
namespace GraphQL.GraphiQLCore
4+
{
5+
public class GraphQLUserContext
6+
{
7+
public ClaimsPrincipal User { get; set; }
8+
}
9+
}

src/GraphQL.GraphiQLCore/Startup.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using GraphQL.Types;
55
using Microsoft.AspNetCore.Builder;
66
using Microsoft.AspNetCore.Hosting;
7+
using Microsoft.AspNetCore.Http;
78
using Microsoft.Extensions.DependencyInjection;
89
using Microsoft.Extensions.Logging;
910

@@ -24,7 +25,10 @@ public void ConfigureServices(IServiceCollection services)
2425
services.AddSingleton<DroidType>();
2526
services.AddSingleton<CharacterInterface>();
2627
services.AddSingleton<EpisodeEnum>();
27-
services.AddSingleton<ISchema>(s => new StarWarsSchema(type => (GraphType) s.GetService(type)));
28+
services.AddSingleton<ISchema>(
29+
s => new StarWarsSchema(new FuncDependencyResolver(type => (GraphType) s.GetService(type))));
30+
31+
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
2832
}
2933

3034
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
@@ -38,7 +42,10 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF
3842

3943
app.UseMiddleware<GraphQLMiddleware>(new GraphQLSettings
4044
{
41-
Schema = app.ApplicationServices.GetService<ISchema>()
45+
BuildUserContext = ctx => new GraphQLUserContext
46+
{
47+
User = ctx.User
48+
}
4249
});
4350
app.UseDefaultFiles();
4451
app.UseStaticFiles();
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
using System;
2-
using GraphQL.Types;
1+
using GraphQL.Types;
32

43
namespace GraphQL.StarWars
54
{
65
public class StarWarsSchema : Schema
76
{
8-
public StarWarsSchema(Func<Type, GraphType> resolveType)
9-
: base(resolveType)
7+
public StarWarsSchema(IDependencyResolver resolver)
8+
: base(resolver)
109
{
11-
Query = (StarWarsQuery)resolveType(typeof (StarWarsQuery));
12-
Mutation = (StarWarsMutation) resolveType(typeof(StarWarsMutation));
10+
Query = resolver.Resolve<StarWarsQuery>();
11+
Mutation = resolver.Resolve<StarWarsMutation>();
1312
}
1413
}
1514
}

0 commit comments

Comments
 (0)