Graphql-dotnet: Steps to get an ASP.Net Core graphql api running, that is backed by EF Core

Created on 2 Feb 2017  路  26Comments  路  Source: graphql-dotnet/graphql-dotnet

A lot of .Net developers like myself are watching this project and eagerly waiting for a chance to start using graphql apis.

However, it is not clear to a graphql newbie like me, what steps are required to use this project to get a full graphql api up and running, which uses EF Queryable...or whether that's currently even possible.

Please shed some light on this, and provide brief steps to get an ASP.Net core graphql api backed by EF Core. This will help the community immensely and we can then contribute back to the project by way of tutorials/videos etc.

Thanks

question

Most helpful comment

I've created simple 'Hello GraphQL!' example based on the example from 'Usage' section (console version), but using ASP.NET Core and Entity Framework Core. I've also briefly described steps while I was coding. Maybe it will be useful. I'm planning to create some more advanced examples:
You can find it here: https://github.com/JacekKosciesza/StarWars

All 26 comments

From the docs: https://github.com/graphql-dotnet/graphql-dotnet/blob/master/docs/getting-started.md

GraphQL isn't tied to any specific database or storage engine and is instead backed by your existing code and data.

This project sticks to the spec as much as possible. So yes, it supports EF. This GraphQL implementation is data agnostic. You can use whatever data store you want.

The existing GraphiQL example uses ASP.NET MVC. I haven't updated it to use ASP.NET Core yet though you should be able to do so with that example? There has been other community members providing additional code, such as middleware, to work with ASP.NET Core.

1) What do you think an EF example would provide over the existing in-memory objects example?
2) This project has supported any data store from the start. What has lead you to think that EF wouldn't be "supported"?
3) Were you aware of the docs I linked to?
4) Are you looking for more of a "pass my EF context to this engine and it should do stuff for me" behavior?

Joe, Thanks for your reply. Yes, I have scoured the docs...but it is still unclear, as to how to make the leap from a console app to an ASP.Net Core webapi, and have it work for EF IQueryables, while avoiding the issues around excessive database queries for joins etc (n+1 issue). I am pretty sure it is possible, but being new to GraphQL (and even .Net core), it is unclear..I am pretty sure I am not alone; this is evidenced by the fact that there is not a single youtube (or anywhere else) tutorial that shows how to build a graphql api on .net. So please help us newbies out.

I would love to be able to get an api running and experiment with Apollo client as I am very familiar with Apollo

Answers to your questions below:

  1. What do you think an EF example would provide over the existing in-memory objects example?
    _I think for most developers, the in-memory objects examples have limited value...What most bread-and-butter .Net developers are looking for is: how I can avoid messy REST api for my next app by using GraphQL, and yet not sacrifice the power of Linq and EF_
  2. This project has supported any data store from the start. What has lead you to think that EF wouldn't be "supported"?
    _I am pretty sure EF is supported...I am just get trying to get my hands on a tutorial that can teach me how_
  3. Were you aware of the docs I linked to?
    _Yes, unfortunately got limited value out of the docs. The docs as they exist today don't help me get my ASP.Net Core graphql api up and running quickly (or at all)_
  4. Are you looking for more of a "pass my EF context to this engine and it should do stuff for me" behavior?
    _Well at this point I am looking for a way to easily generate schema from EF context. Most of the db fields could be made part of the schema automatically but then in case something special needs to be done, how to write a custom resolve function which could leverage the power of Linq_

BTW, this frustration with lack of clear steps to work with IQueryables and EF Core probably led to creation of the graphql-net project, which unfortunately is not being actively developed or maintained.

There's really nothing special that you have to do to use EF. My EF is rusty so this may not be 100% correct usage, but it should get the idea across.

The provided example:

public class StarWarsQuery : ObjectGraphType<object>
{
    public StarWarsQuery(StarWarsData data)
    {
        Name = "Query";

        Field<CharacterInterface>("hero", resolve: context => data.GetDroidByIdAsync("3"));
    }
}

EF Example:

public class StarWarsQuery : ObjectGraphType<object>
{
    public StarWarsQuery()
    {
        Name = "Query";

        Field<CharacterInterface>("hero", resolve: context =>
        {
            using(var db = new MyEfContext())
            {
              return (from d in db.Droids
                     where d.Id == "3"
                     select d).FirstOrDefault();
            }
        });
    }
}

All you have to do is return the object from your data store to the resolver.

I am looking for a way to easily generate schema from EF context

This is unfortunately out of scope for the core project. There are a few "schema generator" projects in the works from other community members though. This one has examples in EF.

I've created simple 'Hello GraphQL!' example based on the example from 'Usage' section (console version), but using ASP.NET Core and Entity Framework Core. I've also briefly described steps while I was coding. Maybe it will be useful. I'm planning to create some more advanced examples:
You can find it here: https://github.com/JacekKosciesza/StarWars

I'm going to go ahead and close this one. I added a link to @JacekKosciesza example in the docs.

https://github.com/graphql-dotnet/graphql-dotnet/blob/master/docs/getting-started.md#how-do-i-use-xyz-ormdatabase-with-graphqlnet

A lot of time has elapsed and this still remains an issue. The examples linked above are poor quality and interestingly, won't provide any examples of mutations.

It is very disheartening that we want to use graphql in .Net and yet there is no quality guidance available on building a small yet fully functional web/mobile app using Graphql.net

@bancroftway the great thing about free and open source software is that if you don't think the previous examples are of high enough quality, you have everything at your disposal to do it yourself. Including writing your own library. If you have any specific questions about this project let me know.

@joemcbride @JacekKosciesza There is a real hunger in the community from people like myself (who hate doing REST webapis the traditional way) for a better solution like graphql. However, Graphql is very new and unfamiliar to us. That is why we are requesting a very small/simple step by step tutorial on using EF Core and graphql.net, both for query and mutations.

Please understand that this is a HUGE issue we are facing. I have spent several hours on google with an an example or tutorial on how to do this, and came up empty.

I would also argue that this will invite more .Net developers to use this great library and push the project to new heights.

PS: BTW, if you search for Graphql .Net, this thread comes up at third position on Google. This should mean that a lot of people are looking for guidance on this subject.

The problem is there is no correct tutorial. And adding a naive implementation would only lure ppl into a false sense of what a real implementation looks like. How you connect an API to a database is just as varied and fraught with GraphQL as it is with WebApi, it's also conceptually the same.

WebAPI you fetch data in your actions and return it, you do the same thing with GraphQL, expect instead of actions you have resolvers. In most cases you probably are going to have a layer between GQL/WebApi and EF, e.g. repository and service patterns. Overall though you can apply all the knowledge you already have in building an API in front of EF and continue to use it here, but the details of how one does that aren't particularly amenable to simple demos.

I think developers can easily figure out and resolve the EF context vs Repository debate themselves. A simple starter tutorial that shows how to achieve mutations in an asp.net core/EF Core is still valuable.

BTW, see this link down in the comments, even the author of the article does not provide an example of a mutation with EF Core, and acknowledges that documentation on mutations with graphql.net is scant.

I just pushed #373 which adds an example mutation to the StarWars sample.

This example, of course, is using an in-memory repository of data. However you save data in EF you would do so in your "repo" class.

Classes of interest:

/// <example>
/// This is an example JSON request for a mutation
/// {
///   "query": "mutation ($human:HumanInput!){ createHuman(human: $human) { id name } }",
///   "variables": {
///     "human": {
///       "name": "Boba Fett"
///     }
///   }
/// }
/// </example>
public class StarWarsMutation : ObjectGraphType<object>
{
    public StarWarsMutation(StarWarsData data)
    {
        Field<HumanType>(
            "createHuman",
            arguments: new QueryArguments(
                new QueryArgument<NonNullGraphType<HumanInputType>> {Name = "human"}
            ),
            resolve: context =>
            {
                var human = context.GetArgument<Human>("human");
                return data.AddHuman(human);
            });
    }
}

public class HumanInputType : InputObjectGraphType
{
    public HumanInputType()
    {
        Name = "HumanInput";
        Field<NonNullGraphType<StringGraphType>>("name");
        Field<StringGraphType>("homePlanet");
    }
}

public class StarWarsData
{
    ...

    public Human AddHuman(Human human)
    {
        human.Id = Guid.NewGuid().ToString();
        _humans.Add(human);
        return human;
    }
}

The above is merged to master and I switched the mutation example in the docs to use that one.

http://graphql-dotnet.github.io/getting-started#mutations

I have written up the article about how to make EF Core and GraphQL.NET work together at https://www.codeproject.com/Articles/1224151/How-to-implement-Generic-Queries-by-combining

I have put together a recent, in-depth guide on using GraphQL.NET with ASP.NET Core 2, GraphiQL and Entity Framework Core 2.

https://fullstackmark.com/post/17/building-a-graphql-api-with-aspnet-core-2-and-entity-framework-core

since i could hardly find a thread about graphQL, i am posting a query here, please don't delete.

I m looking to consume a graphQL API, my project being in c# do i need to write the request as a specific type and then convert to string or basic string would do?

@amaningenium the readme here has a pretty good example https://github.com/graphql-dotnet/graphql-client

Can't help with EF Core, but I created an ASP.NET Core project template you can get started with pretty quickly called ASP.NET Core GraphQL Boxed.

Forget EF for a moment ... I feel like the bit that's missing is some sort of translation that maps from a GraphQL request body to a LINQ expression tree.

For example ...

In WebAPI OData I can do something like this:

public FooController : ODataController<Foo> {  
     DbContext data;
     FooController(DbContext data) { this.data = data; }

     public IHttpActionResult Get(ODataQueryOptions options) 
     {
              return Ok(data.Foos);
     }
}

now (assuming the usual EF and OData model configuration has been done) ... I add my Set to my OData model and the above controller code gives me complete CRUD functionality on my Foo table in the db (overrides for crud methods optional, the get above shown for illustration of my next point).

With a simple GET request to ~/Api/Foo? i can do everything from querying exactly what i need (including other graph related objects), I can also do aggregations ect.

What I think is needed for GraphQL here is some sort of example that works something like this ...

public class MyGraphQuery : ObjectGraphType<object>
{
    public MyGraphQuery()
    {
        Name = "MyQuery";

        Field<Foo>("Foo", resolve: context =>
        {
            using(var db = new MyEfContext())
            {
                 return GraphQLOptions.Apply(db.Foos);
            }
        });
    }
}

The key here being the GraphQLOptions object that translates a request in to the appropriate set of queries on the IQueryable exposed by EF as db.Foos (but as stated above, it doesn't have to be EF).

Not having this it seems whilst GraphQL supports all this querying type stuff we can't really leverage it without having to write lines of code that do the QL to LINQ translation.

My understanding (which may be wrong) is that a GraphQL "Query" is similar to an OData Action that performs a business operation on a CRUD supporting ICollection.

Or have I missed something about the implementation here?
Also where do we get metadata about the graph as it's all on one controller (that according to the samples i've seen only have pieces of the CRUD functionality for 1 or 2 types).

What would really show this off ... would be if someone built a simple demo on top of Northwind or something, it would be crazy easy to get everything except the GraphQL bit as a base start point.

Did a bit of digging through the info above these are pretty good ...

http://fiyazhasan.me/tag/graphql-dotnet/
https://fullstackmark.com/post/17/building-a-graphql-api-with-aspnet-core-2-and-entity-framework-core

... looks to me like this can be closed now :)

Note that the simple examples shown above where a new DbContext is created _per type_ is bypassing much of the efficiencies that EF provides as explained here. You ideally want to have a single context _per GraphQL query_ not per database query.

But, shouldn't GraphQL implementation be done by MSFT EF Core team? So we have official & proper implementation by the vendor of EF.

@TehWardy did you find answers to your question? Im facing the same issue. All the GraphQL hype sounds good (compared to OData where community and tools is not extremly vivid), but when I actually want to understand a simple querying use case where a combination of pagination, filtering and ordering should be applied to a EF Core IQueryable/DbSet then I seem to not find _any_ good example (I could only find some unrealistic inmemory List examples).

Odata works just fine with an IQueryable, and as EF Core exposes IQueryables the combination is extremly simple and powerfull.

[EnableQuery] public IQueryable<Person> GetPersons(){ return dataContext.Persons; }
is basically all the code I need to expose Persons that can be searched, paged, filtered, ordered at the same time and the generated SQL is just as good as I could have written it. How to do that with GraphQL?

@jannikbuschke & @TehWardy There is a library written by @SimonCropp / GraphQL.EntityFramework that we are using to implement cursor based pagination in GraphQL. It utilizes EFCore as the data access layer to implement your graphql-dotnet types. It has a many impressive querying features you get for free, including pagination. Though I should mention that there are some major flaws to this library. Namely:

  1. GraphQL fragments are currently not supported.
  2. There are some type introspection issues for parameters. Query parameters for this library always introspect as a String array, which can break type generation tools like Apollo CLI.
  3. Deeply nested relations sometimes need to be explicitly included. Which can be hard to figure out if you are a novice. Though this is not really the fault of the library, as it is simply a more fundamental problem of data access querying in general.

@ZenSoftware thanks for the ping

GraphQL fragments are currently not supported.

Yep still happy to accept a PR for that. or if someone really needs it, and cant spend the time themselves, I can quote an hourly rate

There are some type introspection issues for parameters.

Not sure what u mean by that? can u add a failing test as a PR?

Deeply nested relations sometimes need to be explicitly included.

the full doco is here https://github.com/SimonCropp/GraphQL.EntityFramework#includes-and-navigation-properties. in the majority of cases includes are derived by the graphql query and do not need to be explicitly included. happy to accept feedback if someone finds ways to tweak the current implementation

Guys, I too am new to this concept of GraphQL and have searched a lot for this combo of GraphQL, EF Core and SQL. Here is the link to the tutorial that helped me learn a bit. Thought it might be of help.

https://www.c-sharpcorner.com/article/graphql-in-net-core-web-api-with-entity-framework-core-part-one/
(it has five parts.)

I would be grateful if somebody shares any idea about using the schema first approach (please do not suggest the basic example present in graphql website.Need a two-level queriable example. ) and launching it in the GraphQL UI playground. Anyone?

As this issue is nearly 2 years old now I figured I should feed back what happened in my case ...

I hit a ton of issues making ODat awork under .Net 4.x then finally hit walls due to problems in the .Net 4.x version of EF6 so I took some time to ask questions like this and the feedback / information was so limited and hard to get I simply converted my entire solution so .Net Core 2.2 and EF Core.

I say simply ... it wsa hard work, i'm still finding bugs / issues but they do all seem to be readily solvable meanwhile I can still see GraphQL questions cropping up that are essentially pieces of getting full CRUD working with EF so I figured it wasn't worth the risk to try and adopt the technology.

I often bump in to people that have come from a PHP or Node background for their stack who rave about the value of using GraphQL so I may at some point look in to adding GraphQL to our API along side the OData one.

If this technology is really going to take off though it needs a dead simple "getting started" where a developer can pull in a nuget package for GraphQL and another for EF, write the model classes or whatever and be up and running in an hour or so and I really got the feeling it's not quite there unless you have prior knowledge of GraphQL.

Was this page helpful?
0 / 5 - 0 ratings