8.0 KiB
sidebar_position | title |
---|---|
2 | Graphql |
For our examples we will use a small example project based on an SQLite database.
This example is available here.
Creating a client application
We will create a client application to consume GraphQL.
Create a new Blazor WASM app.
Edit the appsettings.json
file, adding an address to the GraphQL app:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"GraphQLURI": "https://localhost:44371/graphql",
"AllowedHosts": "*"
}
Install the GraphQL.Client
package in its latest version.
Or using the Package Manager console: PM> Install-Package GraphQL.Client
Install the GraphQL serialization nuget GraphQL.Client.Serializer.Newtonsoft
:
PM> Install-Package GraphQL.Client.Serializer.Newtonsoft
After installation, we will save it in the Program
class:
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddScoped<IGraphQLClient>(s => new GraphQLHttpClient(builder.Configuration["GraphQLURI"], new NewtonsoftJsonSerializer()));
await builder.Build().RunAsync();
}
The next step is to create the OwnerConsumer
class, which will store all requests and mutations:
public class OwnerConsumer
{
private readonly IGraphQLClient _client;
public OwnerConsumer(IGraphQLClient client)
{
_client = client;
}
}
Now let's register this class:
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddScoped<IGraphQLClient>(s => new GraphQLHttpClient(builder.Configuration["GraphQLURI"], new NewtonsoftJsonSerializer()));
builder.Services.AddScoped<OwnerConsumer>();
await builder.Build().RunAsync();
}
We have finished everything regarding the configuration.
Creating model classes
We will create the model classes so that we can use the data from our queries:
public enum TypeOfAccount
{
Cash,
Savings,
Expense,
Income
}
public class Account
{
public Guid Id { get; set; }
public TypeOfAccount Type { get; set; }
public string Description { get; set; }
}
public class Owner
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public ICollection<Account> Accounts { get; set; }
}
Now we are going to create the Input
class for the mutation actions.
public class OwnerInput
{
public string Name { get; set; }
public string Address { get; set; }
}
We have now prepared everything and are ready to start creating queries and mutations.
Creating queries and mutations to consume the GraphQL API
Open the OwnerConsumer
class and add the GetAllOwners
method:
public async Task<List<Owner>> GetAllOwners()
{
var query = new GraphQLRequest
{
Query = @"
query ownersQuery{
owners {
id
name
address
accounts {
id
type
description
}
}
}"
};
var response = await _client.SendQueryAsync<ResponseOwnerCollectionType>(query);
return response.Data.Owners;
}
As you can see, we are creating a new GraphQLRequest
object which contains a Query
property for the query we want to send to the GraphQL API.
This query is the same one you can use with the UI.Playground
tool.
To execute the query, call the SenQueryAsync
method which accepts a response type (as a generic parameter) and the query.
Finally, the code returns the list of owners from this response.
We don't have the ResponseOwnerCollectionType
class, so let's create a new ResponseTypes
folder and inside it create the two new classes:
public class ResponseOwnerCollectionType
{
public List<Owner> Owners { get; set; }
}
public class ResponseOwnerType
{
public Owner Owner { get; set; }
}
Get Query
public async Task<Owner> GetOwner(Guid id)
{
var query = new GraphQLRequest
{
Query = @"
query ownerQuery($ownerID: ID!) {
owner(ownerId: $ownerID) {
id
name
address
accounts {
id
type
description
}
}
}",
Variables = new { ownerID = id }
};
var response = await _client.SendQueryAsync<ResponseOwnerType>(query);
return response.Data.Owner;
}
Create Mutation
public async Task<Owner> CreateOwner(OwnerInput ownerToCreate)
{
var query = new GraphQLRequest
{
Query = @"
mutation($owner: ownerInput!){
createOwner(owner: $owner){
id,
name,
address
}
}",
Variables = new {owner = ownerToCreate}
};
var response = await _client.SendMutationAsync<ResponseOwnerType>(query);
return response.Data.Owner;
}
Update Mutation
public async Task<Owner> UpdateOwner(Guid id, OwnerInput ownerToUpdate)
{
var query = new GraphQLRequest
{
Query = @"
mutation($owner: ownerInput!, $ownerId: ID!){
updateOwner(owner: $owner, ownerId: $ownerId){
id,
name,
address
}
}",
Variables = new { owner = ownerToUpdate, ownerId = id }
};
var response = await _client.SendMutationAsync<ResponseOwnerType>(query);
return response.Data.Owner;
}
Delete Mutation
public async Task<Owner> DeleteOwner(Guid id)
{
var query = new GraphQLRequest
{
Query = @"
mutation($ownerId: ID!){
deleteOwner(ownerId: $ownerId)
}",
Variables = new { ownerId = id }
};
var response = await _client.SendMutationAsync<ResponseOwnerType>(query);
return response.Data.Owner;
}
Use in a Blazor page
Create a new Consume.razor
page to test our code:
@page "/consume"
<h3>Consume</h3>
@if (Owner != null)
{
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Address</th>
</tr>
</thead>
<tbody>
@foreach (var item in Owner)
{
<tr>
<td>@item.Id</td>
<td>@item.Name</td>
<td>@item.Address</td>
</tr>
}
</tbody>
</table>
}
Create the page code:
public partial class Consume
{
private List<Owner> Owner;
[Inject]
public OwnerConsumer Consumer { get; set; }
protected override async Task OnInitializedAsync()
{
this.Owner = await Consumer.GetAllOwners();
}
}