Intégrer GraphQL dans Blazor

Apprenez à intégrer un service GraphQL dans une application Blazor avec différentes requêtes de service et UI Telerik pour les contrôles Blazor.
Dans cet article, vous apprendrez à intégrer un service GraphQL dans vos applications basées sur Blazor en créant un exemple d’application CRUD et en utilisant Progress Telerik pour Composants du blazor. Cela vous donnera une meilleure perspective pour gérer des intégrations similaires dans vos propres projets. Commençons!
Important: Toutes les opérations effectuées sur le service GraphQL dans cet exercice ne sont pas persistantes, vous recevrez donc des réponses représentant leur exécution correcte, mais vous ne verrez pas le changement reflété dans la base de données finale.
Création de l’échantillon de projet
Pour acquérir une expérience pratique avec ce sujet, commençons par créer un exemple de projet. Dans le sélecteur de modèle, vous devez configurer une nouvelle solution à l’aide du Application Web Blazor modèle. Sélectionnez le Mode de rendu interactif comme Server
le Emplacement d’interactivité comme Global
et le Cadre comme .NET 9.0
comme suit:
Ensuite, vous devez configurer le projet à utiliser Telerik UI pour Blazor composants en suivant le Guide dans la documentation officiellequi nous permettra de créer des interfaces rapides et esthétiques.
Générer facilement des modèles de données
Pour notre échantillon de projet, nous utiliserons le Graphqlzero Service, qui permet une pratique gratuite avec leur API.
Bien que nous puissions démarrer le projet en générant des requêtes manuellement dans les variables de texte, cela peut être contre-productif à long terme pour des raisons multiples:
- La définition du schéma peut changer.
- Les requêtes doivent être recherchées manuellement et mises à jour dans les chaînes.
- Il n’est pas dactylographié, ce qui peut provoquer des erreurs.
Pour résoudre ces problèmes, nous utiliserons le GraphQlClientGenerator projet. Ce projet est régulièrement maintenu, et ils ont ajouté un support pour l’intégration avec C # 9, permettant de générer des modèles de données de manière super simple.
Le processus se compose des étapes suivantes:
- Installer le
GraphQlClientGenerator
Package NuGet. - Ouvrez le fichier .csproj. (Vous pouvez le faire en double-cliquant sur le projet.)
- Ajouter un nouveau
PropertyGroup
Section avec les informations suivantes:
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<GraphQlClientGenerator_ServiceUrl>https://graphqlzero.almansi.me/api</GraphQlClientGenerator_ServiceUrl>
<GraphQlClientGenerator_Namespace>$(RootNamespace)</GraphQlClientGenerator_Namespace>
<GraphQlClientGenerator_CustomClassMapping>Consumption:ConsumptionEntry|Production:ProductionEntry|RootMutation:TibberMutation|Query:Tibber</GraphQlClientGenerator_CustomClassMapping>
<GraphQlClientGenerator_IdTypeMapping>String</GraphQlClientGenerator_IdTypeMapping>
</PropertyGroup>
Dans le code ci-dessus, vous pouvez voir que j’ai ajouté l’URL pointant vers le service GraphQL; Vous pouvez remplacer ce point de terminaison par un autre pour générer des modèles à partir de ce point de terminaison. De même, j’ai ajouté GraphQlClientGenerator_IdTypeMapping
ce qui permet de modifier la génération de l’ID de ligne. En effet, il génère un type de GUID, mais le service utilise des identifiants numériques.
- Modifier le
ItemGroup
avec la configuration suivante:
<ItemGroup>
<PackageReference Include="GraphQL.Client" Version="6.1.0" />
<PackageReference Include="GraphQL.Client.Serializer.Newtonsoft" Version="6.1.0" />
<PackageReference Include="GraphQlClientGenerator" Version="0.9.24" IncludeAssets="analyzers" />
<PackageReference Include="Telerik.UI.for.Blazor" Version="6.2.0" />
<CompilerVisibleProperty Include="GraphQlClientGenerator_ServiceUrl" />
<CompilerVisibleProperty Include="GraphQlClientGenerator_Namespace" />
<CompilerVisibleProperty Include="GraphQlClientGenerator_IdTypeMapping" />
</ItemGroup>
Le code ci-dessus installera les bibliothèques nécessaires pour travailler avec GraphQL.Client
qui nous permettra d’invoquer facilement les services GraphQL.
De même, vous pouvez voir que j’ai ajouté quelques CompilerVisibleProperty
directives qui rendent les propriétés MSBuild visibles pour l’analyseur pendant la compilation. Et, enfin, dans le GraphQlClientGenerator
référence du package, j’ai ajouté le IncludeAssets
attribut pour inclure les analyseurs générés. Tout cela permet une compilation réussie et est nécessaire pour que les entités soient générées automatiquement.
Une fois la compilation effectuée, si nous allons à Dependencies
| Analyzers
| GraphQlClientGenerator
| GraphQlClientGenerator.GraphQlClientSourceGenerator
| GraphQlClient.cs
nous verrons que dans cette classe, des méthodes et des modèles ont été créés qui nous permettra de travailler avec le schéma GraphQL d’une manière tapée de C #.
Création d’une application CRUD pour gérer les publications
Il existe plusieurs façons de travailler avec un service GraphQL, que ce soit en utilisant HTTPClient
, Strawberry Shake
entre autres. Dans notre cas, nous utiliserons le GraphQL.Client
Package NuGet, qui est l’un des plus utilisés et a été installé si vous avez ajouté les références de package à l’intérieur ItemGroup
. Avant de créer la première page du système, nous devons aller à Program.cs
et ajouter une instance singleton de GraphQLHttpClientOptions
comme suit:
var builder = WebApplication.CreateBuilder(args);
...
builder.Services.AddSingleton(provider =>
{
var options = new GraphQLHttpClientOptions
{
EndPoint = new Uri("https://graphqlzero.almansi.me/api")
};
return new GraphQLHttpClient(options, new NewtonsoftJsonSerializer());
});
var app = builder.Build();
Cela nous permettra de réutiliser cette instance comme spécifié dans la documentation de la bibliothèque.
Création d’une page pour afficher les données de service
Commençons par créer la page pour afficher les articles existants dans la base de données. Pour ce faire, nous créerons un nouveau composant de page appelé PostList
à l’intérieur Components
dossier. Dans cette page, nous profiterons de la puissance des contrôles de Telerik, en définissant l’interface graphique comme suit:
@page "/posts"
@using BlazorGraphQLDemo.Models
@using GraphQL
@using GraphQL.Client.Http
@using GraphQL.Client;
@using GraphQL.Client.Serializer.Newtonsoft
@using Telerik.Blazor.Components
@rendermode InteractiveServer
@inject GraphQLHttpClient HttpClient
@inject NavigationManager Navigationn
@inject IJSRuntime JSRuntime
<h3>Post List</h3>
<TelerikGrid Data="@posts" Pageable="true" PageSize="10" Sortable="true" Groupable="true">
<GridColumns>
<GridColumn Field="Id" Title="ID" Width="50px" />
<GridColumn Field="Title" Title="Title" />
<GridColumn Field="Body" Title="Body" />
</GridColumns>
</TelerikGrid>
Dans le code ci-dessus, nous avons utilisé un TelerikGrid
Contrôle pour afficher rapidement les données sous forme de grille. Le Data
la propriété s’attend à une variable appelée posts
que nous définissons dans la section Code comme suit:
@code {
private List<Post> posts = new List<Post>();
protected override async Task OnInitializedAsync()
{
await LoadPosts();
}
private async Task LoadPosts()
{
var builder =
new QueryQueryBuilder()
.WithPosts(
new PostsPageQueryBuilder()
.WithData(
new PostQueryBuilder()
.WithAllScalarFields()));
var query = new GraphQLRequest
{
Query = builder.Build()
};
var response = await HttpClient.SendQueryAsync<PostListData>(query);
posts = response.Data.Posts.Data;
}
}
Décrivons un peu ce qui s’est passé dans le code ci-dessus. Nous commençons par définir le posts
variable dans laquelle les postes obtenus du service seront stockés.
Ensuite, dans le OnInitializedAsync
Méthode, le LoadPosts
La méthode est invoquée, dans laquelle la requête tapée qui générera la requête finale à exécuter par rapport au service GraphQL est définie. J’ai placé un commentaire pour que vous puissiez voir la requête obtenue à partir de cette exécution.
Puis une instance de type GraphQLRequest
est créé qui permet d’envoyer des demandes au service GraphQL.
Et, enfin, la demande est exécutée via le SendQueryAsync
Méthode, passant la requête générée comme paramètre, désérialisant la réponse au PostListData
taper et attribuer le résultat à posts
.
L’étape suivante consiste à créer un nouveau dossier appelé Models
dans lequel nous créerons une classe appelée GraphQLResponse
comme suit:
public class GraphQlResponse
{
public PostsData Posts { get; set; }
}
public class PostsData
{
public List<Post> Data { get; set; }
}
Allons maintenant au fichier situé dans Components
| Layout
| NavMenu.razor
que nous allons modifier en ajoutant un nouvel élément au menu:
<div class="nav-item px-3">
<NavLink class="nav-link" href="posts">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Posts
</NavLink>
</div>
Une fois que nous aurons appliqué le code ci-dessus, vous verrez l’écran suivant lors de l’exécution de l’application et de la navigation vers le Posts
Option dans le menu:
Il est incroyable de voir comment, dans quelques lignes de code, nous affichons des informations obtenues à partir du service de manière claire et présentable.
Création de nouveaux enregistrements
Maintenant que nous avons récupéré tous les enregistrements et les avons affichés dans un Blazor DataGridVoyons comment créer un nouvel enregistrement. Pour cela, utilisons le Tellikbutton et Télérikwindow Contrôles dans le but de pouvoir ajouter un nouvel enregistrement sans quitter la page. Nous y parviendrons en ajoutant les lignes suivantes au PostList.razor
page:
<TelerikGrid ...>
<TelerikButton OnClick="@ShowCreatePostDialog">Create New Post</TelerikButton>
<TelerikWindow @bind-Visible="@isCreatePostDialogVisible">
<WindowContent>
<EditForm Model="@newPost" OnValidSubmit="@CreatePost">
<DataAnnotationsValidator />
<ValidationSummary />
<div>
<label>Title:</label>
<InputText @bind-Value="newPost.Title" />
</div>
<div>
<label>Body:</label>
<InputText @bind-Value="newPost.Body" />
</div>
<TelerikButton ButtonType="@ButtonType.Submit">Save</TelerikButton>
<TelerikButton OnClick="@CloseCreatePostDialog">Cancel</TelerikButton>
</EditForm>
</WindowContent>
</TelerikWindow>
D’un autre côté, ajoutons trois méthodes dans la section de code pour gérer la visibilité des fenêtres, ainsi que pour effectuer le fonctionnement de la création du nouvel enregistrement:
@code {
private bool isCreatePostDialogVisible;
private Post newPost = new Post();
...
private async Task CreatePost()
{
var mutation =
new MutationQueryBuilder()
.WithCreatePost(
new PostQueryBuilder().WithAllScalarFields(),
new CreatePostInput
{
Body = newPost.Body,
Title = newPost.Title
}
)
.Build(Formatting.Indented, 2);
var request = new GraphQLRequest
{
Query = mutation
};
var graphQLResponse = await HttpClient.SendMutationAsync<GraphQlResponse>(request);
posts.Add(graphQLResponse.Data.CreatePost);
isCreatePostDialogVisible = false;
}
private void ShowCreatePostDialog()
{
newPost = new Post();
isCreatePostDialogVisible = true;
}
private void CloseCreatePostDialog()
{
isCreatePostDialogVisible = false;
}
}
Dans la section de code ci-dessus, nous avons créé le ShowCreatePostDialog
et CloseCreatePostDialog
Méthodes en tant que méthodes auxiliaires qui permettent de gérer la visibilité de la fenêtre, tandis que le CreatePost
La méthode est responsable de la définition d’une mutation pour créer un nouveau message avec les informations insérées par l’utilisateur.
Enfin, nous devons modifier le GraphQlResponse
classe en ajoutant le CreatePost
propriété, puisque c’est la définition renvoyée par le service:
public class GraphQlResponse
{
public PostsData Posts { get; set; }
public Post CreatePost { get; set; }
}
Lors de l’exécution de l’application, vous verrez un bouton sous le contrôle de TelerikGrid qui, lorsqu’il apprenne, affichera une nouvelle fenêtre pour saisir les données du nouveau post:
Voyons maintenant comment supprimer un record.
Suppression d’un record
La prochaine fonctionnalité que nous ajouterons à l’application sera de supprimer un message de la liste. Profitons de la fonction de contrôle TelerikGrid qui permet à l’ajout de commandes d’exécuter des tâches comme suit:
<TelerikGrid ...>
<GridColumns>
...
<GridCommandColumn>
<GridCommandButton Command="Delete" OnClick="@DeletePost">Delete</GridCommandButton>
</GridCommandColumn>
</GridColumns>
</TelerikGrid>
Avec le code ci-dessus, nous avons ajouté un bouton à l’interface graphique que nous pouvons lier à une méthode personnalisée pour supprimer un post, qui est le suivant:
@code{
...
private async Task DeletePost(GridCommandEventArgs args)
{
var post = args.Item as Post;
var idParameter = new GraphQlQueryParameter<string>("id", "ID!", null);
var mutation =
new MutationQueryBuilder()
.WithParameter(idParameter)
.WithDeletePost(idParameter);
var request = new GraphQLRequest
{
Query = mutation.Build(Formatting.Indented, 2),
Variables = new { id = post.Id }
};
if(graphQLResponse.Data.DeletePost)
{
posts.Remove(post);
await JSRuntime.InvokeVoidAsync("alert", $"Post with ID {post.Id} was deleted");
}
}
}
Dans le code ci-dessus, le idParameter
Le paramètre est défini que nous passons comme paramètre à la mutation et à la définition du deletePost
opération. Vous pouvez voir la requête générée dans le code commenté. De même, pendant la création du GraphQLRequest
L’instance est où la valeur du id
la variable est définie.
Une autre chose que nous devons faire est de définir une nouvelle classe pour représenter la réponse de suppression comme suit:
public class DeleteResponse
{
public bool DeletePost { get; set; }
}
Lors de l’exécution du code ci-dessus, vous pouvez voir un nouveau bouton avec le titre de suppression, qui, appuyé, supprimera le message de la liste:
Une fois que nous avons implémenté la fonctionnalité pour supprimer un article, voyons comment modifier un article existant.
Édition d’un message
La dernière opération que nous devons implémenter est de pouvoir modifier un message. Nous allons aborder cela différemment, en modifiant l’élément sur une autre page. Commençons par ajouter la nouvelle commande pour accéder à la nouvelle page dans le contrôle TelerikGrid:
<TelerikGrid ...>
<GridColumns>
...
<GridCommandColumn>
...
<GridCommandButton Command="Edit" OnClick="@EditPost">Edit</GridCommandButton>
</GridCommandColumn>
</GridColumns>
</TelerikGrid>
Définissons la commande personnalisée en ajoutant la méthode suivante à la section Code:
private async Task EditPost(GridCommandEventArgs args)
{
var post = args.Item as Post;
Navigation.NavigateTo($"/editpost/{post.Id}");
}
Le code ci-dessus reçoit le paramètre de l’élément sur lequel le bouton est enfoncé puis naviguer vers le editpost
Page passant l’ID d’enregistrement en tant que paramètre. Cette page n’a pas encore été créée, nous allons donc procéder à la création du nouveau composant de page à l’intérieur du Components
dossier avec le nom EditPost.razor
qui ressemble à ceci:
@page "/editpost/{id:int}"
@using BlazorGraphQLDemo.Models
@using GraphQL
@using GraphQL.Client.Http
@using Telerik.Blazor.Components
@inject NavigationManager Navigation
@rendermode InteractiveServer
@inject GraphQLHttpClient HttpClient
@inject IJSRuntime JSRuntime
<h3>Edit Post</h3>
<EditForm Model="@post" OnValidSubmit="@UpdatePost">
<DataAnnotationsValidator />
<ValidationSummary />
<div>
<label>Title:</label>
<InputText @bind-Value="post.Title" />
</div>
<div>
<label>Body:</label>
<InputText @bind-Value="post.Body" />
</div>
<TelerikButton ButtonType="@ButtonType.Submit">Save</TelerikButton>
<TelerikButton OnClick="@Cancel">Cancel</TelerikButton>
</EditForm>
Comme nous l’avons mentionné précédemment, ce composant représente une nouvelle page qui attend l’ID de la publication que nous voulons modifier. Sur cette page, nous utilisons un EditForm
Composant pour modifier les informations de publication. Ci-dessous, je vous montre le code pour effectuer à la fois la récupération du message demandé et la modification de la publication:
@code {
[Parameter] public int Id { get; set; }
private Post post = new Post();
protected override async Task OnInitializedAsync()
{
await LoadPost();
}
private async Task LoadPost()
{
var idParameter = new GraphQlQueryParameter<string>("id", "ID!", null);
var postFragment = new PostQueryBuilder()
.WithId()
.WithTitle()
.WithBody();
var query = new QueryQueryBuilder()
.WithParameter(idParameter)
.WithPost(
postFragment,
idParameter
);
var request = new GraphQLRequest
{
Query = query.Build(Formatting.Indented),
Variables = new { id = Id }
};
var response = await HttpClient.SendQueryAsync<GraphQlResponse>(request);
post = response.Data.Post;
}
private async Task UpdatePost()
{
var idParameter = new GraphQlQueryParameter<string>("id", "ID!", null);
var inputParameter = new GraphQlQueryParameter<UpdatePostInput>("input", "UpdatePostInput!", new UpdatePostInput());
var mutation = new MutationQueryBuilder()
.WithParameter(idParameter)
.WithParameter(inputParameter)
.WithUpdatePost(
new PostQueryBuilder()
.WithId()
.WithTitle()
.WithBody(),
idParameter,
inputParameter
);
var request = new GraphQLRequest
{
Query = mutation.Build(Formatting.Indented),
Variables = new
{
id = post.Id,
input = new { title = post.Title, body = post.Body }
}
};
var response = await HttpClient.SendQueryAsync<GraphQlResponse>(request);
await JSRuntime.InvokeVoidAsync("alert", $"Post updated successfully. Title: {response.Data.UpdatePost.Title}, Body: {response.Data.UpdatePost.Body}");
Navigation.NavigateTo("/posts");
}
private void Cancel()
{
Navigation.NavigateTo("/posts");
}
}
Dans le code ci-dessus, dans le LoadPost
Méthode, je vous montre un moyen par lequel vous pourriez représenter l’utilisation de fragments qui peuvent être réutilisés dans d’autres requêtes de manière dactylographiée.
De même, dans le UpdatePost
Méthode, un paramètre d’entrée appelé UpdatePostInput
Défini dans le schéma GraphQL est utilisé et est nécessaire pour mettre à jour un élément (comme on peut le voir dans la requête générée). Ce paramètre avec idParameter
sont utilisés pour créer la requête qui permettra à l’exécution de la mutation pour modifier un message. D’un autre côté, le Cancel
La méthode effectue la navigation vers la page précédente sans exécuter de modifications.
Enfin, vous devez mettre à jour le GraphQlResponse
classe comme suit pour soutenir les réponses du service:
public class GraphQlResponse
{
public PostsData Posts { get; set; }
public Post CreatePost { get; set; }
public Post UpdatePost { get; set; }
public Post Post { get; set; }
}
Lors de l’application des modifications ci-dessus, vous verrez un nouveau bouton dans le contrôle TelerikGrid qui permettra à la navigation sur la nouvelle page de rédiger un élément. Lorsque vous effectuez la modification et l’appuyez sur le bouton Enregistrer, vous verrez les modifications appliquées à l’entité comme suit:
Avec cela, nous avons terminé la mise en œuvre de toutes les opérations CRUD sur le service GraphQL.
Conclusion
Tout au long de cet article, vous avez appris à intégrer un service GraphQL dans une application Blazor en effectuant différents types de requêtes de service, ainsi qu’à exploiter la UI Telerik pour les commandes de blazor pour créer des interfaces graphiques rapides et belles. Il est temps pour vous de vous rendre au travail et d’étendre l’application encore plus loin avec de nouvelles fonctionnalités!
Vous voulez l’essayer vous-même? Telerik UI pour Blazor Livré avec un essai gratuit de 30 jours.
Source link