Moving REST To GraphQL  With Asp.net Core & Entity Framework Core.

Moving REST To GraphQL With Asp.net Core & Entity Framework Core.

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

source: GraphQl

GraphQL queries are used to query the GraphQL server for the data that the client needs. What is interesting about GraphQL is that clients can write custom made queries based on the individual client’s needs. This means that GraphQL enables the client to ask for exactly what they want using a query and also returns a response with only what was asked. This approach gives the client more power.

Benefits of GraphQL:

  • Good fit for complex systems and microservices: By integrating multiple systems behind its API, GraphQL unifies them and hides their complexity. The GraphQL server is then responsible for fetching the data from the existing systems and packaging it up in the GraphQL response format.
  • Fetch data in single call and avoid multiple round trips:GraphQl is less chatty than Rest and rest api’s required multiple round trips between client and resources to fetch the data and return back to client to render on calling apps.

GraphQL solves the roundtrip problem by allowing the client to create a single query which calls several related functions (or resolvers) on the server to construct a response with multiple resources – in a single request. This is a much more efficient method of data delivery requiring fewer resources than multiple roundtrips.

  • Avoid Over/Under data fetching problems:REST api responses are known for either containing too much data or not enough of it, it’s very hard to design an API flexible enough to fulfill every client’s precise data needs. GraphQL solves this efficiency problem by fetching the exact data in a single request.

Building a GraphQL Service in ASP.NET Core

  1. Installing GraphQL in .net core: Since GraphQL support is not provided within ASP.NET Core, you need a Nuget package. Below are the most commonly used nuget packages used in .net core.
1
2
3

2. Setting up graph types: GraphTypes is a Class which derives from the ObjectGraphType base class that implements IObjectGraphType. Now in the constructor you can declare fields for this graph type. 

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using GraphQL;
using GraphQL.Types;
using WebApiWithGraphQl.Data.Entities;
using WebApiWithGraphQl.Repositories;

namespace WebApiWithGraphQl.GraphQ.Types
{
public class EmployeType : ObjectGraphType<Employee>
{
public EmployeType(EmployeeRepository employeeRepository)
{
Field(x => x.EmployeId);
Field(x => x.Name);
Field<EmployeeTypeEnumType>("EmploymentType", resolve: context => context.Source.EmployeType.ToString());

Field<ListGraphType<AddressType>>(

"Address",
resolve: context => employeeRepository.GetAdddressById(context.Source.EmployeId)
);
}
}
}

3. Define Resolver:Now that we have a Employe graph type we need another class that knows how to get Employees. I call it EmployeQuery which also derives from ObjectGraphType.
In the constructor I declare one field, this time I explicitly say that this field must return a list of EmployeType objects. As you can see even list is a special graph type.
Then I give the field a name and in a lambda I can now specify where the data should come from, in other words how to data should be resolved.

Resolvers are the functions responsible for supplying the data requested by the query and is the integration point between our application’s data source and the GraphQL infrastructure.

namespace WebApiWithGraphQl.GraphQ.Query
{
public class EmployeeQuery:ObjectGraphType
{
public EmployeeQuery(EmployeeRepository employeeRepository)
{
Field(
"Employees",
resolve: context => employeeRepository.GetAllEmployees()
);
}
}
}

2. Set up schema: A GraphQL schema is at the center of any GraphQL server implementation and describes the functionality available to the clients which connect to it.

GraphQL implements a human-readable schema syntax known as its Schema Definition Language, or “SDL”. The SDL is used to express the types available within a schema and how those types relate to each other. 

using GraphQL;
using GraphQL.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WebApiWithGraphQl.GraphQ.Query;

namespace WebApiWithGraphQl.GraphQl
{
public class EmployeSchema :Schema
{
public EmployeSchema(IDependencyResolver resolver ):base(resolver)
{
Query = resolver.Resolve();
}
}
}

Configuring Asp.net Core With GraphQL Middleware

To setup GraphQL in your project and start using the scheme we created go to the startup class of your application.

  • Add the dependency resolver to get the query instance.
  • AddGraphQL extension method to register all the types GraphQL .NET uses
  • AddGraphTypes which will scan the assembly for all ObjectGraphTypes and register them automatically in the container using the specified lifetime.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("EmpoyeeDBConnectionString")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info { Title = "My API", Version = "v1" });
});
services.AddScoped(s => new FuncDependencyResolver(s.GetRequiredService));
services.AddScoped();
services.AddScoped();

services.AddGraphQL(o => { o.ExposeExceptions = false; })
.AddGraphTypes(ServiceLifetime.Scoped);
}

Now we have to inject graphQL middleware by calling UseGraphQL extension method in configure method of startup.cs class.

public void Configure(IApplicationBuilder app, IHostingEnvironment env,EmployeeContext context)
{
app.UseGraphQL();
app.UseGraphQLPlayground(new GraphQLPlaygroundOptions());
context.Seed();

app.UseHttpsRedirection();
app.UseMvc();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "API with graphQl V1");
});

}

Till now we have setup all the mandatory steps for graphQL integration with asp.net core api.If you want to see the playground UI as soon as you start the API go to the properties of the project and select the debug tab. Activate launch browser there and type in ui/playground as the url.

5

When the browser opens take a look at the schema tab on the right side. The metadata of the schema has been read by the playground.
Using this metadata information the query editor can have intellisense.
Type the query in the pic. It gets all products but only the names and descriptions. When I execute it you can see that the result is JSON and the data is contained in the data root node which has a products array with the data I asked for.

6
PlaygroundQueryExecution

Advertisements

WebApi Exception: Multiple Action were found that match the request.

Usually webapi controller contains GET,GET(id),Post,Put,Patch & Delete methods but sometimes we need to create multiple get or post method or more custom methods to support http verbs.

Let say we have existing Get() method and now we want to add one more custom method names as “GetALL()” to support http Get verb.My Api Controller code looks like:

c2

When you defined your new method with http Get verb along with existing Get() method  and run webapi than below error comes:

C1

WebApiConfig.cs for above code which is created by default when new api project created.

C3

So talk about why this error comes if every thing is perfect in code.So look at the defined route in config file and .In webapi routing only controller name is mentioned in route template and there is no action like (Get,Post or any Custom Action Name) are defined.

Here is the difference in mvc routing and Webapi routing. In mvc routing action name are by default included in Url’s while in webapi actions names are not mandatory.

MVC Route: url: “{controller}/{action}/{id}”

WebApi Route: routeTemplate: “api/{controller}/{id}”

So when ever any request comes to webapi,it always goes to default http verbs and if default GET or Post methods used then it returns a response to the client.

But when we have defined some custom methods along with default Api methods than same request will thrown an exception because now there are multiple action methods that supports http verbs  and server not able to identify which method have to execute.

Why this happened because we have not defined any specific action name in webapi Route.

So what is the solution of this problem as we need many custom action names along with default http verbs in our webapi solution to solve the day-to-day business needs.So question comes in mind whether custom method names are allowed in webapi or not.

Then answer is “yes”,off-course we can add custom action names as much as we want but some changes have to make in webapi routing to support custom action names.

To support custom action method names we have to add {action} with controller name in default route as per below:

routeTemplate: “api/{controller}/{action}/{id}”

Now Complete Webapiconfig.cs after make some changes:

c4

Now Test our methods with these changes.

.1.when request goes to default methods:

C5

2.When request goes to custom action method (GetAll)

C6

 

 

 

 

 

 

WebApi Field Level Response Without Implementing Odata.

Download Complete Project: WebApiFieldLevelSelection

When you are writing a RESTful web API you often want to allow clients to feed a list of fields to the API that the clients need. The reason is to return only the useful data to the client. Say for example, you have an entity called Product that has many properties. The client may need only a few properties of the Product object. If you return the entire object every time the client asks for a product.

it unnecessarily wastes bandwidth and increases the response time. So to avoid that you can accept a list of fields the client wants and return only those. How can you do that?

Odata is best way to achieve this where you can use $Select command to fetch specific database fields in response.

Problem comes when webapi not implementing odata then how can achieve this functionality ?

To achieve this you have to use some basic .net objects like dynamic,expendoObject or  generic collections etc.

Let’s resolve the problem step by step:

  1. Create empty Webapi Project with controller name as “ProductCategory” with Two Get method.one is parameter less and other with string parameter that will accept comma separated field list in request.
  2. Get() method will return all fields of database in response while Get(string fields) method accept list of fields and return desired fields in response.
  3. In below example i have use hardcoded list with dummy values.You may replace it with actual database.

    ProductCategroyController.cs

w1.png

 DynamicObject Method:

DynamicObject accept the list of fields  and return object.here I have use .net reflection to get the value of each fields and respective value to dictionary<string,object> object. later this dictionary object pass to linq query.

w2.PNG

ApiHelper.cs

w3.PNG

OUTPUT:

  1.  When user pass two fields (productid and productName) as query string in request.you can see only two fields are coming in json response.

w4

  1.  When User pass three fields (productId,ProductName,Price) as query string in request.You can see now three fields are coming with json response.

w5.PNG

So you can see how you can implement field level selection on webapi without Odata implementation.