---
sidebar_position: 2
title: Graphql
---

Pour nos exemples nous allons utiliser un petit projet d'exemple basé sur une base de données SQLite.

Cette exemple est disponible [ici](/DemoGraphQL.zip).

## Création d'une application client

Nous allons créer une application client permettant de consommer GraphQL.

Créer une nouvelle application Blazor WASM.

Modifier le fichier `appsettings.json`, en ajoutant une adresse vers l'application GraphQL :

```csharp title="wwwroot/appsettings.json"
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "GraphQLURI": "https://localhost:44371/graphql",
  "AllowedHosts": "*"
}
```

Installer le package `GraphQL.Client` dans sa dernière version.

![required library](/img/graphql/29-GraphQL.CLient-new-version.png)

Ou en utilisant la console Package Manager : `PM> Install-Package GraphQL.Client`

Installer le nuget de serialisation de GraphQL `GraphQL.Client.Serializer.Newtonsoft` :

![required library](/img/graphql/30-GraphQL-Serializer-Newtonsoft.png)

`PM> Install-Package GraphQL.Client.Serializer.Newtonsoft`

Après l'installation, nous allons l'enregistrer dans la classe `Program` : 

```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();
}
```

L'étape suivante consiste à créer la classe `OwnerConsumer`, qui stockera toutes les requêtes et mutations :

```csharp title="OwnerConsumer.cs"
public class OwnerConsumer
{
    private readonly IGraphQLClient _client;

    public OwnerConsumer(IGraphQLClient client)
    {
        _client = client;
    }
}
```

Maintenant, enregistrons cette classe :

```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();
}
```

Nous avons tout terminé concernant la configuration.


## Création des classes de modèle

Nous allons créer les classes de modèle afin de pouvoir utiliser les données de nos requêtes :

```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; }
}
```

Maintenant nous allons créer la classe `Input` pour les actions de mutation.

```csharp title="Models/OwnerInput.cs"
public class OwnerInput
{
    public string Name { get; set; }
    public string Address { get; set; }
}
```

Nous avons maintenant tout préparé et sommes prêts à commencer à créer des requêtes et des mutations.

## Création de requêtes et de mutations pour consommer l'API GraphQL

Ouvrer la classe `OwnerConsumer` et ajoutons la méthode `GetAllOwners` :

```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;
}
```

Comme vous pouvez le voir, nous créons un nouvel objet `GraphQLRequest` qui contient une propriété `Query` pour la requête que nous voulons envoyer à l'API GraphQL. 
Cette requête est la même que celle que vous pouvez utiliser avec l'outil `UI.Playground`.

Pour exécuter la requête, appeler la méthode `SenQueryAsync` qui accepte un type de réponse (comme paramètre générique) et la requête. 
Enfin, le code renvoie la liste des propriétaires à partir de cette réponse.

Nous n'avons pas la classe `ResponseOwnerCollectionType`, créons donc un nouveau dossier `ResponseTypes` et à l'intérieur créer les deux nouvelles 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;
}
```

## Utilisation dans une page Blazor

Créer une nouvelle page `Consume.razor` pour tester notre 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>
}
```

Créer le code de la page :

```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();
	}
}
```
