Fermer

juin 9, 2023

Bonnes pratiques—Création d’un nouveau projet

Bonnes pratiques—Création d’un nouveau projet


Lors du développement d’une nouvelle application pour le web, certaines précautions méritent attention, telles que l’expérience utilisateur, les performances et la sécurité, entre autres. Consultez ce billet de blog de la série ASP.NET Core Basics pour un ensemble de bonnes pratiques à examiner lorsque vous démarrez un nouveau projet Web.

Pour créer une nouvelle application web, il ne faut pas seulement répondre aux spécifications techniques avec les règles métier. Bien plus, il existe des facteurs qui, s’ils ne sont pas pris en compte, peuvent compromettre l’ensemble du fonctionnement de l’application.

C’est pourquoi le but de cet article est de présenter un ensemble de bonnes pratiques essentielles au succès d’une application Web dans ASP.NET Core.

Pourquoi devrions-nous nous soucier des meilleures pratiques ?

Bien que la plupart des développeurs connaissent ou aient entendu parler des meilleures pratiques, la vérité est qu’ils ne les prennent pas toujours en compte lors de la création d’une nouvelle application.

Les raisons de ne pas tenir compte des meilleures pratiques vont du manque de connaissances du programmeur au manque de temps pour réfléchir à des solutions plus intelligentes et plus sûres pour résoudre un problème ou créer une nouvelle fonction.

Quelle que soit la raison, nous devons garder à l’esprit qu’il devrait toujours y avoir un endroit où utiliser les meilleures pratiques, car le succès ou l’échec d’une application dépend beaucoup de la façon dont elle a été construite.

Imaginez le scénario suivant : en tant que développeur, vous êtes chargé de créer un système d’enregistrement qui a de nombreuses fonctions et doit avoir un écran de connexion avec authentification, mais au départ, peu d’utilisateurs auront accès au système.

Comme votre délai est court, vous décidez de créer un système d’authentification simple et peu sécurisé, après tout, seuls quelques utilisateurs seront autorisés à y accéder. Mais imaginez qu’après quelques mois, le système se développe rapidement et que des centaines ou des milliers d’utilisateurs y accèdent maintenant. Que se passerait-il avec le système d’authentification fragile que vous avez créé si un pirate informatique contraire à l’éthique l’envahissait et procédait à la capture des données de centaines ou de milliers d’utilisateurs ?

Les meilleures pratiques sont certainement la meilleure solution pour éviter cela et d’autres catastrophes.

Meilleures pratiques pour la création d’un nouveau projet ASP.NET Core

Lors de la création d’un nouveau projet, nous devons toujours considérer l’utilisation des meilleures pratiques. Même s’il faut plus de temps pour choisir quelle est la meilleure approche pour développer une fonction donnée, cela en vaut la peine. Les meilleures pratiques évitent plusieurs problèmes futurs qui, en plus de prendre plus de temps pour la résolution, peuvent mettre en danger le bon fonctionnement de l’ensemble du programme.

Vous trouverez ci-dessous une liste des meilleures pratiques que vous pouvez toujours prendre en compte lors de la création d’une nouvelle application ASP.NET Core.

Pensez toujours à utiliser des méthodes asynchrones

Contrairement aux méthodes synchrones, les méthodes asynchrones permettent de démarrer une certaine action sans que la précédente soit terminée. De cette façon, plusieurs fonctions peuvent être exécutées simultanément et terminées en fonction du temps dont chacune a besoin.

Imaginez le scénario suivant : Vous allez payer sur un site de vente en ligne avec une carte de crédit. Lorsque vous cliquez sur « effectuer un paiement », vous recevez généralement une notification indiquant que votre paiement est en cours de traitement, et selon la façon dont cela se produit, vous recevrez une notification indiquant le succès ou l’erreur générée. En attendant, vous êtes libre de naviguer sur le site Web ou de faire quoi que ce soit d’autre, car il utilise une méthode asynchrone.

Mais si nous devions utiliser l’approche synchrone, en cliquant sur « effectuer un paiement », vous devriez attendre tout le processus d’authentification de la carte et de confirmation de la passerelle de paiement, ce qui pourrait prendre un temps considérable, bloquant toute autre action.

Ci-dessous deux exemples. Le premier montre un point de terminaison synchrone, et le second montre comment le même point de terminaison peut être modifié pour fonctionner de manière asynchrone, où le mot await est utilisé avant d’appeler la fonction dont le nom contient « Async ». Dans cet exemple, nous utilisons la fonction asynchrone native d’EF Core, mais vous pouvez créer vos propres fonctions asynchrones.

app.MapGet("/books/id", (ApplicationDBContext db, Guid id) =>
{
	var book = db.Books.FirstOrDefault(b => b.Id == id);

	return book is not null ? Results.Ok(book) : Results.NotFound();
})
.WithName("GetBooksById")
.WithOpenApi();
app.MapGet("/books/id", async (ApplicationDBContext db, Guid id) =>
{
	var book = await db.Books.FirstOrDefaultAsync(b => b.Id == id);

	return book is not null ? Results.Ok(book) : Results.NotFound();
})
.WithName("GetBooksById")
.WithOpenApi();

👉 Si vous voulez en savoir plus sur la (a)synchronicité dans .NET, je vous propose de lire cet article : Faire un petit-déjeuner asynchrone dans .NET.

Utiliser correctement les journaux

Les journaux sont importants dans toute application Web car ils permettent d’enregistrer les événements survenus lors de l’exécution d’un programme.

Cependant, si les journaux ne sont pas utilisés de manière responsable, le bon fonctionnement de l’application peut être compromis. Après tout, les journaux peuvent ne pas être enregistrés correctement, ce qui rend difficile l’identification d’un problème, et l’utilisation exagérée des journaux peut également devenir un goulot d’étranglement pour l’application.

Voici quelques conseils pour une bonne utilisation des logs.

Niveaux de journalisation

Les niveaux de journal sont utilisés pour identifier la catégorie qui correspond le mieux à l’enregistrement de journal. Vous trouverez ci-dessous un exemple de chacun des niveaux.


_logger.LogTrace($"Processing request from the user: {userName}");


_logger.LogDebug($"The zip code is default for the user: {userName}");


_logger.LogInformation($"Starting execution...");


_logger.LogWarning($"User:{userName} without address");


_logger.LogError($"Username property cannot be null");


_logger.LogCritical(ex.Message, "An error occurred in our systems. Please contact immediately the support team!");

Envisagez d’utiliser des bibliothèques tierces

Bien que .NET dispose déjà d’un système de journalisation en natif, il existe des outils qui peuvent être d’une grande aide en raison de ses diverses possibilités, dont Serilog.

Sérilog fournit une journalisation de diagnostic pour les fichiers, les consoles et encore plus d’endroits est facile à configurer, et il dispose d’une grande variété de fonctions pour les applications modernes.

Utilisez Telerik REPL pour tester et partager du code

Progrès Telerik REPL pour ASP.NET Core est un terrain de jeu où vous pouvez tester toutes vos idées, ainsi qu’apprendre et développer des trucs sympas.

Utilisez le REPL pour partager des extraits de code, modifier des démos en place, jouer avec des composants existants, présenter votre travail et gagner du temps avec un codage simple. De plus, son utilisation est gratuite !

Écrire du code propre

L’écriture de code propre permet d’effectuer efficacement la maintenance du programme en réduisant les erreurs et en augmentant la qualité des applications.

Vous trouverez ci-dessous une liste d’exemples d’extraits de code indiquant d’abord la voie à éviter, puis la voie à suivre.

Commutateur Cas

	switch (item.Name)
	{
		case "Rin Tin Tin":
			typeOfAnimal = "dog";
			break;
		case "Mr. Bigglesworth":
			typeOfAnimal = "cat";
			break;

		case "K-9":
			typeOfAnimal = "fish";
			break;
		default:
			typeOfAnimal = "undefined";
			break;
}
typeOfAnimal = item.Name switch
	{
		"Rin Tin Tin" => "dog",
		"Mr. Bigglesworth" => "cat",
		"K-9" => "fish",
		_ => "undefined",
	};

👉 Vous pouvez accéder et tester l’extrait de code REPL ici : Bon boîtier de commutateur.

Utilisation de l’opérateur conditionnel « ? » (Ternaire) à la vérification de la valeur nulle

L’utilisation de l’opérateur ternaire pour vérifier les valeurs nulles est une solution intelligente qui réduit plusieurs lignes de code comme on peut le voir dans l’exemple ci-dessous :

public static string CheckPetnameWrong(string petName)
{
		string defaultPetName = "Bingo";
		
		if (!string.IsNullOrEmpty(petName))
	{
		return petName;
	}
	else
	{
		return defaultPetName;
	}
}
public static string CheckPetnameCorrect(string petName) => !string.IsNullOrEmpty(petName) ? petName : "Bingo";

👉 Vous pouvez accéder et tester l’extrait de code REPL ici : Utilisation de l’opérateur conditionnel.

Gagnez du temps avec des composants prêts à l’emploi

Le développement de composants tels que les grilles de données, les tableaux de données et la pagination, entre autres, peut demander beaucoup d’efforts si vous allez les créer à partir de zéro, sans parler de la création du HTML, du CSS, du JavaScript et même du backend pour les rendre fonctionnels.

Heureusement, il existe des plates-formes qui ont déjà ces composants et bien d’autres prêts à l’emploi, et certainement le plus approprié est Interface utilisateur Telerik pour ASP.NET Core.

Voir ci-dessous un exemple de Grille de données réalisé avec Telerik UI pour ASP.NET Core. En quelques lignes seulement, vous disposez d’une grille de données complète avec des fonctions de pagination, d’édition et de suppression.

👉 Vous pouvez l’essayer et obtenir le code source ici au Grille de données REPL.

grille de données

Assurer la sécurité des applications

La sécurité est l’un des sujets les plus importants lors de la création d’une nouvelle application car tout le travail effectué peut être compromis s’il est fragile.

Actuellement, JWT (JSON Web Tokens) est l’une des méthodes les plus connues et les plus fiables pour mettre en œuvre un système d’authentification et d’autorisation.

JWT est un standard ouvert qui vous permet de transmettre en toute sécurité des données entre un client et un serveur sous la forme d’un objet JSON.

Bien qu’il s’agisse d’un système simple, la mise en œuvre de l’authentification et de l’autorisation avec JWT dans ASP.NET Core est un peu complexe, mais vous pouvez suivre ce guide—Autorisation et authentification dans les API minimales— qui vous apprend à implémenter JWT à partir de zéro dans une API minimale.

Toujours créer des tests unitaires et d’intégration

Tester une application est essentiel pour s’assurer qu’elle remplira correctement les fonctions pour lesquelles elle a été conçue.

Pour s’en assurer, il existe des tests unitaires et d’intégration, qui peuvent être développés avant, pendant ou après la création du programme.

Les tests unitaires simulent l’exécution d’une unité de processus déterminante. Par exemple, dans une fonction qui vérifie si le numéro de téléphone d’un utilisateur est valide, nous pouvons créer un test qui utilise un faux numéro pour s’assurer que la méthode qui effectue la vérification fonctionne correctement.

Les tests d’intégration, quant à eux, servent à vérifier le bon fonctionnement des intégrations de notre application avec des processus ou des applications externes. Par exemple, imaginez que votre application récupère les données d’un utilisateur à partir d’une API externe. Pour s’assurer que cela fonctionne, il est possible de créer un test d’intégration qui simule l’appel à l’API et crée des scénarios de réussite ou d’erreur.

Il est important de souligner que de nombreuses entreprises ont comme exigence de base la couverture d’au moins 80% du code avec des tests unitaires et d’intégration.

Pour créer des situations qui simuleront l’exécution de fonctions de programme, on utilise normalement des mocks, qui en programmation désignent des données et de fausses fonctions utilisées pour faciliter la mise en œuvre de tests unitaires.

Télérik JustMock est un outil rapide, flexible et complet pour créer des tests unitaires.

👉 Vous pouvez consulter cet article—Utilisation de simulations lors des tests unitaires des applications ASP.NET Core— qui vous apprend à implémenter des tests unitaires à l’aide de JustMock.

Envisagez d’utiliser la mise en cache distribuée

Un cache distribué est un cache qui peut être partagé par plusieurs serveurs, est généralement géré en tant que service externe et est disponible pour toutes les applications sur le serveur.

L’utilisation de la mise en cache distribuée peut améliorer les performances et l’évolutivité d’une application ASP.NET Core car elle envoie des données cohérentes entre les requêtes. Il est également capable de survivre aux redémarrages du serveur et aux déploiements d’applications et il n’utilise pas de mémoire locale.

Il existe d’excellents outils qui aident à mettre en œuvre la mise en cache distribuée, dont le plus connu est peut-être Redis. Redis est un magasin de structure de données en mémoire open source (sous licence BSD) qui, en plus de la base de données NoSQL, est également utilisé pour la mise en cache et le courtage de messages. Des entreprises comme Stackoverflow, Twitter et GitHub utilisent Redis dans leurs systèmes.

L’extrait de code suivant montre comment Redis peut être utilisé pour mettre en cache une API minimale basée sur ASP.NET Core :

app.MapGet("/orders/redis", async (IDistributedCache distributedCache) =>
{
	using (var session = DocumentStoreHolder.Store.OpenSession())
	{
		var orders = session.Query<Order>().ToList();
		
		var cacheKey = "orderList";
		
		string serializedOrders;
		
		var orderList = new List<Order>();
		
		var redisOrders = await distributedCache.GetAsync(cacheKey);
		
		if (redisOrders != null)
		{
			serializedOrders = Encoding.UTF8.GetString(redisOrders);
			orderList = JsonConvert.DeserializeObject<List<Order>>(serializedOrders);
}
else
{
	orderList = orders.ToList();

	serializedOrders = JsonConvert.SerializeObject(orderList);

		redisOrders = Encoding.UTF8.GetBytes(serializedOrders);

		var options = new DistributedCacheEntryOptions()
			.SetAbsoluteExpiration(DateTime.Now.AddMinutes(10))
			.SetSlidingExpiration(TimeSpan.FromMinutes(2));

		distributedCache?.SetAsync(cacheKey, redisOrders, options);
	}
	return orderList;
   }
});

👉 Vous pouvez consulter cet article qui explique comment implémenter la mise en cache distribuée avec Redis à partir de zéro : Amélioration des performances avec la mise en cache distribuée.

Utilisez les Tag Helpers autant que possible

Tag Helpers est une syntaxe alternative pour HTML Helpers, mais il fournit certaines fonctionnalités qui étaient difficiles ou impossibles à réaliser avec les méthodes d’assistance.

La syntaxe des Tag Helpers ressemble beaucoup aux HTML Helpers mais est rendue par Razor sur le serveur.

Le plus grand avantage de l’utilisation de Tag Helpers est la réduction de la quantité de code que nous devons écrire lors de la création d’une nouvelle application et aussi le fait qu’ils créent une couche abstraite entre l’interface utilisateur et le code côté serveur. Un autre point important est que les Tag Helpers ne remplacent pas les balises HTML, nous pouvons donc les utiliser ensemble, selon l’endroit où elles s’intègrent le mieux.

👉 Vous trouverez ci-dessous un exemple d’utilisation de Tag Helpers. Vous pouvez tester et voir le résultat dans le REPL.

Exemple de code utilisant Tag Helpers avec Telerik UI pour ASP.NET Core :


@addTagHelper *, Kendo.Mvc

<kendo-datasource name="dataSource1" type="DataSourceTagHelperType.Ajax" server-operation="false" page-size="10">
	<schema>
		<model id="ProductID">
			<fields>
				<field name="ProductName" type="string"></field>
				<field name="UnitPrice" type="number"></field
				<field name="UnitsInStock" type="number"></field
				<field name="Discontinued" type="bool"></field
			</fields>
		</model>
	</schema>
	<transport>
		<read url="@Url.Action("TagHelper_Products_Read", "DataSource")" />
	</transport>
</kendo-datasource>

<kendo-grid name="grid" datasource-id="dataSource1" auto-bind="false" height="300">
	<pageable enabled="true">
	</pageable>
	<columns>
		<column field="ProductName"></column>
		<column field="UnitPrice" format="{0:c}"></column>
		<column field="UnitsInStock"></column>
		<column field="Discontinued"></column>
	</columns>
	<scrollable enabled="true" />
</kendo-grid>
<br/>

<script>
$(function (){
	dataSource1.read();
});
</script>

Optimiser l’accès aux données

L’accès à la base de données est une routine courante dans une application Web et peut être exécuté des milliers de fois en fonction de la situation. Vous devez donc toujours réfléchir à la manière d’optimiser les requêtes vers la base de données pour éviter d’éventuels goulots d’étranglement.

Vous trouverez ci-dessous une liste des meilleures pratiques d’accès aux données que vous pouvez utiliser lors de la création d’une nouvelle application ASP.NET Core.

  • Créez une logique simple : essayez toujours de garder le code aussi simple que possible. Il existe des alternatives telles que l’utilisation de fonctions, d’opérateurs ternaires, LINQ et autres qui aident à créer un code propre et performatif.

  • Utiliser des méthodes asynchrones pour les appels d’API : L’utilisation de l’asynchronicité permet d’exécuter plusieurs actions en même temps, car elles ne dépendent pas les unes des autres, ce qui se traduit par un gain de performances important.

  • Utiliser des requêtes LINQ agrégées pour filtrer les enregistrements : LINQ dispose de plusieurs méthodes utiles pour filtrer les requêtes de base de données, telles que .Where(), .Sum() et .Select() méthodes d’extension.

  • Obtenez uniquement les données nécessaires : Chaque fois que le système doit effectuer une recherche dans la base de données, envisagez de ne renvoyer que les données vraiment nécessaires. Pour cela, ajoutez des filtres à la requête.

  • Envisagez d’utiliser des requêtes sans suivi : pour la lecture des données, envisagez d’utiliser des requêtes sans suivi via Entity Framework. Cela libère la charge de travail utilisée pour surveiller les modifications apportées aux valeurs d’entité de la base de données. Utilisez simplement le .AsNoTracking() méthode de rallonge.

Conclusion

Comme nous le savons, il est pratiquement impossible de créer un système qui fonctionne parfaitement à tous points de vue, mais si vous suivez les meilleures pratiques décrites tout au long de cet article, votre application sera certainement protégée contre de nombreux bogues et défaillances pouvant survenir en cours de route. Par conséquent, dans la mesure du possible, essayez de les utiliser dans vos projets.


Trouve plus Articles sur les bases d’ASP.NET Core ici.




Source link