by Paul Carson 03/22/2023
For this project, I wanted to highlight some of the versatility of GraphQL using a publically available database. The use case I was envisioning is an existing database that needs to be exposed for different clients. GraphQL is a fantastic API technology providing the client with exactly what date it needs, reducing the amount of unnecessary data that is transferred over the network. This is in contrast to REST typically requires multiple requests to return data, resulting in slower and less efficient communication. It also has strongly typed schema so it's easy to understand and use. In addition, it provides an evolutionary design, so the API can evolve without breaking existing clients. This is because the client specifies what data it needs, and the server can add new fields and types to the schema without affecting existing clients. Overall, GraphQL is a more efficient, flexible, and developer-friendly alternative to REST.
I implemented a GraphQL API using .NET Core and the Hot Chocolate library to exposed the Wide World Importers database. This allows clients to query the data more efficiently by requesting only the data they need.
HotChocolate.AspNetCore
HotChocolate.AspNetCore.Playground
HotChocolate.Data.EntityFramework
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
{
"ConnectionStrings": {
"WideWorldImporters": "YourConnectionStringHere"
}
}
dotnet ef dbcontext scaffold "Server=(local);Database=WideWorldImporters;User Id=myUsername;Password=myPassword;" Microsoft.EntityFrameworkCore.SqlServer -o Models
public class Query
{
[UseDbContext(typeof(WideWorldImportersDbContext))]
public IQueryable GetCustomers([ScopedService] WideWorldImportersDbContext context)
{
return context.Customers;
}
[UseDbContext(typeof(WideWorldImportersDbContext))]
public IQueryable GetCustomerTransactions([ScopedService] WideWorldImportersDbContext context,
decimal amountGreaterThan)
{
return context.CustomerTransactions
.Include(ct => ct.Customer)
.Where(ct => ct.TransactionAmount > amountGreaterThan);
}
}
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.MapGraphQL();
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddDbContextFactory(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("WideWorldImportersConnection")));
builder.Services
.AddRouting()
.AddGraphQLServer()
.AddQueryType()
.AddType();
builder.Services.AddScoped(sp => sp.GetRequiredService());
To see what we get from all this, we can the Hot Chocolate UI: Banana Cake Pop. It exposes the schema and the data it can return. This is where the flexibility really shines. Let's walk through it