You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

333 lines
8.0 KiB

---
sidebar_position: 2
title: Graphql
---
For our examples we will use a small example project based on an SQLite database.
This example is available [here](/DemoGraphQL.zip).
## 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:
```csharp title="wwwroot/appsettings.json"
{
"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.
![required library](/img/graphql/29-GraphQL.CLient-new-version.png)
Or using the Package Manager console: `PM> Install-Package GraphQL.Client`
Install the GraphQL serialization nuget `GraphQL.Client.Serializer.Newtonsoft`:
![required library](/img/graphql/30-GraphQL-Serializer-Newtonsoft.png)
`PM> Install-Package GraphQL.Client.Serializer.Newtonsoft`
After installation, we will save it in the `Program` class:
```csharp {8} title="Program.cs"
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:
```csharp title="OwnerConsumer.cs"
public class OwnerConsumer
{
private readonly IGraphQLClient _client;
public OwnerConsumer(IGraphQLClient client)
{
_client = client;
}
}
```
Now let's register this class:
```csharp {9} title="Program.cs"
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:
```csharp title="Models/TypeOfAccount.cs"
public enum TypeOfAccount
{
Cash,
Savings,
Expense,
Income
}
```
```csharp title="Models/Account.cs"
public class Account
{
public Guid Id { get; set; }
public TypeOfAccount Type { get; set; }
public string Description { get; set; }
}
```
```csharp title="Models/Owner.cs"
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.
```csharp title="Models/OwnerInput.cs"
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:
```csharp title="OwnerConsumer.cs"
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:
```csharp title="ResponseTypes/ResponseOwnerCollectionType.cs"
public class ResponseOwnerCollectionType
{
public List<Owner> Owners { get; set; }
}
```
```csharp title="ResponseTypes/ResponseOwnerType.cs"
public class ResponseOwnerType
{
public Owner Owner { get; set; }
}
```
### Get Query
```csharp title="OwnerConsumer.cs"
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
```csharp title="OwnerConsumer.cs"
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
```csharp title="OwnerConsumer.cs"
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
```csharp title="OwnerConsumer.cs"
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:
```html title="Pages/Consume.razor"
@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:
```csharp title="Pages/Consume.razor.cs"
public partial class Consume
{
private List<Owner> Owner;
[Inject]
public OwnerConsumer Consumer { get; set; }
protected override async Task OnInitializedAsync()
{
this.Owner = await Consumer.GetAllOwners();
}
}
```