paint-brush
Cómo dominar la API web .NET 8: de la configuración a la seguridad: los 50 mejores consejospor@ssukhpinder
871 lecturas
871 lecturas

Cómo dominar la API web .NET 8: de la configuración a la seguridad: los 50 mejores consejos

por Sukhpinder Singh22m2024/04/03
Read on Terminal Reader

Demasiado Largo; Para Leer

Desde la configuración inicial del proyecto utilizando la CLI de .NET hasta la configuración de middleware, controladores y servicios, aprenda cada paso para crear una API sólida. Descubra las mejores prácticas para la inyección de dependencias, acciones asincrónicas y manejo de excepciones para crear aplicaciones web escalables y eficientes.
featured image - Cómo dominar la API web .NET 8: de la configuración a la seguridad: los 50 mejores consejos
Sukhpinder Singh HackerNoon profile picture
0-item
1-item
2-item
3-item
4-item

Desde la configuración inicial del proyecto utilizando la CLI de .NET hasta la configuración de middleware, controladores y servicios, aprenda cada paso para crear una API sólida. Descubra las mejores prácticas para la inyección de dependencias, acciones asincrónicas y manejo de excepciones para crear aplicaciones web escalables y eficientes.

1. Configuración de un proyecto de API web .NET 8

Concepto

Utilice la CLI de .NET para crear un nuevo proyecto de API web. Esto configura una estructura básica del proyecto que incluye Program.cs para el inicio y un controlador WeatherForecast como ejemplo.

Ejemplo de código

 dotnet new webapi -n MyWebApi

2. Program.cs: configuración API mínima

Concepto

.NET 8 continúa la tendencia hacia API mínimas, lo que le permite configurar servicios y puntos finales de manera simplificada y concisa directamente en el archivo Program.cs.

Ejemplo de código

 var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => "Hello, World!"); app.Run();

3. Definición de un controlador

Concepto

Los controladores manejan las solicitudes HTTP entrantes y responden al cliente. Se definen heredando de ControllerBase y anotando con [ApiController].

Ejemplo de código

 [ApiController] [Route("[controller]")] public class MyController : ControllerBase { [HttpGet] public IActionResult Get() => Ok("Hello from MyController"); }

4. Inyección de dependencia en controladores

Concepto

La inyección de dependencias (DI) integrada de .NET Core facilita la administración de dependencias. Puede inyectar servicios en sus controladores a través de sus constructores.

Ejemplo de código

 public class MyService { public string GetMessage() => "Injected message"; } public class MyController : ControllerBase { private readonly MyService _myService; public MyController(MyService myService) { _myService = myService; } [HttpGet] public IActionResult Get() => Ok(_myService.GetMessage()); }

5. Configuración de servicios

Concepto

Los servicios (como contextos de bases de datos, servicios personalizados, etc.) se configuran en el archivo Program.cs, lo que los hace disponibles para la inyección de dependencias en toda su aplicación.

Ejemplo de código

 builder.Services.AddScoped<MyService>();

6. Configuración basada en el entorno

Concepto

.NET admite archivos de configuración específicos del entorno (appsettings.json, appsettings.Development.json, etc.), lo que permite diferentes configuraciones según el entorno de la aplicación.

Ejemplo de código

 // appsettings.Development.json { "Logging": { "LogLevel": { "Default": "Debug" } } }

7. software intermedio

Concepto

Los componentes de middleware forman una canalización que maneja solicitudes y respuestas. Se puede crear middleware personalizado para cuestiones transversales como el registro o el manejo de errores.

Ejemplo de código

 app.Use(async (context, next) => { // Custom logic before passing to the next middleware await next(); // Custom logic after executing the next middleware });

8. Enrutamiento

Concepto

El enrutamiento en .NET Web API se logra mediante el enrutamiento de atributos en controladores y métodos de acción. Esto permite que las URL se asignen directamente a las acciones del controlador.

Ejemplo de código

 [HttpGet("myaction/{id}")] public IActionResult GetAction(int id) => Ok($"Action with ID = {id}");

9. Encuadernación de modelos

Concepto

El enlace de modelo asigna automáticamente datos de solicitudes HTTP a parámetros de métodos de acción. Admite tipos complejos, incluidos cuerpos JSON y parámetros de cadenas de consulta.

Ejemplo de código

 public class MyModel { public int Id { get; set; } public string Name { get; set; } } [HttpPost] public IActionResult PostAction([FromBody] MyModel model) => Ok(model);

10. Validación de datos

Concepto

Las anotaciones de datos se pueden utilizar para validar los datos del modelo. El atributo [ApiController] aplica automáticamente la validación y responde con 400 si el modelo no es válido.

Ejemplo de código

 public class MyModel { [Required] public int Id { get; set; } [StringLength(100)] public string Name { get; set; } }

11. Acciones asincrónicas

Concepto

Las acciones asincrónicas mejoran la escalabilidad al liberar subprocesos mientras se espera que se completen las operaciones de E/S. Utilice la palabra clave async y devuelva Task o Task<IActionResult>.

Ejemplo de código

 [HttpGet("{id}")] public async Task<IActionResult> GetAsync(int id) { var result = await _service.GetByIdAsync(id); return Ok(result); }

12. Manejo de excepciones a nivel mundial

Concepto

El manejo global de excepciones permite el procesamiento centralizado de errores, el registro y las respuestas API estandarizadas en excepciones no controladas.

Ejemplo de código

 app.UseExceptionHandler(a => a.Run(async context => { var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>(); var exception = exceptionHandlerPathFeature.Error; // Log the exception, generate a custom response, etc. context.Response.StatusCode = 500; await context.Response.WriteAsJsonAsync(new { Error = "An unexpected error occurred" }); }));

13. Control de versiones de API

Concepto

El control de versiones de API ayuda a gestionar los cambios en la API a lo largo del tiempo. La plataforma .NET admite el control de versiones mediante una cadena de consulta, una ruta URL o un encabezado de solicitud.

Ejemplo de código

 builder.Services.AddApiVersioning(options => { options.AssumeDefaultVersionWhenUnspecified = true; options.DefaultApiVersion = new ApiVersion(1, 0); options.ReportApiVersions = true; });

14. Negociación de contenidos

Concepto

La negociación de contenido permite que una API proporcione diferentes formatos de respuesta según el encabezado Aceptar de la solicitud, lo que permite la compatibilidad con formatos como JSON, XML, etc.

Ejemplo de código

 builder.Services.AddControllers() .AddXmlDataContractSerializerFormatters();

15. Configuración de serialización JSON personalizada

Concepto

Personalice el formato de respuesta JSON, como nombrar camelCase o ignorar valores nulos, configurando los ajustes del serializador JSON.

Ejemplo de código

 builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; options.JsonSerializerOptions.IgnoreNullValues = true; });

16. Configurar CORS

Concepto

El intercambio de recursos entre orígenes (CORS) permite llamar a su API desde aplicaciones web alojadas en diferentes dominios. Configure la política CORS según sus requisitos.

Ejemplo de código

 builder.Services.AddCors(options => { options.AddPolicy("AllowSpecificOrigin", builder => builder.WithOrigins("http://example.com")); }); app.UseCors("AllowSpecificOrigin");

17. Autenticación

Concepto

Proteja su API habilitando la autenticación, que verifica la identidad de los usuarios o servicios que realizan solicitudes.

Ejemplo de código

 builder.Services.AddAuthentication("Bearer") .AddJwtBearer(options => { options.Authority = "https://your-auth-server"; options.Audience = "your-api"; });

18. Autorización

Concepto

Después de la autenticación, la autorización determina si un usuario autenticado tiene permiso para realizar una acción o acceder a un recurso.

Ejemplo de código

 [Authorize] public class SecureController : ControllerBase { // Action methods here }

19. Integración Swagger/OpenAPI

Concepto

Swagger (OpenAPI) proporciona documentación interactiva para su API, lo que permite a los desarrolladores comprenderla y consumirla fácilmente.

Ejemplo de código

 builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); app.UseSwagger(); app.UseSwaggerUI();

20. Registro

Concepto

.NET Core proporciona un marco de registro integrado que puede registrar mensajes en varias salidas (consola, ventana de depuración, servicios externos, etc.).

Ejemplo de código

 logger.LogInformation("This is an informational message"); app.Use(async (context, next) => { logger.LogError("This is an error message before the next middleware"); await next.Invoke(); // Log after calling the next middleware });

21. Usando Entity Framework Core

Concepto

Entity Framework Core es un ORM utilizado para el acceso a datos en aplicaciones .NET. Le permite consultar y manipular datos utilizando objetos fuertemente tipados.

Ejemplo de código

 public class MyDbContext : DbContext { public MyDbContext(DbContextOptions<MyDbContext> options) : base(options) {} public DbSet<MyModel> MyModels { get; set; } }

22. Migraciones en Entity Framework Core

Concepto

Las migraciones le permiten aplicar control de versiones al esquema de su base de datos mediante el seguimiento de los cambios en sus modelos de datos.

Ejemplo de código

 dotnet ef migrations add InitialCreate dotnet ef database update

23. Patrón de repositorio

Concepto

El patrón Repositorio abstrae la capa de datos, lo que hace que su aplicación sea más modular y más fácil de mantener.

Ejemplo de código

 public interface IRepository<T> { Task<IEnumerable<T>> GetAllAsync(); Task<T> GetByIdAsync(int id); // Other methods... } public class MyRepository<T> : IRepository<T> where T : class { private readonly MyDbContext _context; public MyRepository(MyDbContext context) { _context = context; } // Implement methods... }

24. Pruebas unitarias

Concepto

Las pruebas unitarias garantizan que su API web funcione correctamente al probar unidades individuales de código de forma aislada.

Ejemplo de código

 public class MyControllerTests { [Fact] public async Task Get_ReturnsExpectedValue() { // Arrange var serviceMock = new Mock<IMyService>(); serviceMock.Setup(service => service.GetAsync()).ReturnsAsync("test"); var controller = new MyController(serviceMock.Object); // Act var result = await controller.Get(); // Assert Assert.Equal("test", result.Value); } }

25. Integración con un front-end

Concepto

.NET Web API puede servir como backend para una aplicación front-end, proporcionando servicios RESTful.

Ejemplo de código

 fetch('https://localhost:5001/mycontroller') .then(response => response.json()) .then(data => console.log(data));

26. Controles de salud

Concepto

Las comprobaciones de estado proporcionan una forma de monitorear el estado de su aplicación y sus dependencias, lo que es útil para arquitecturas de microservicios.

Ejemplo de código

 builder.Services.AddHealthChecks(); app.MapHealthChecks("/health");

27. Uso de SignalR para comunicación en tiempo real

Concepto

SignalR habilita la funcionalidad web en tiempo real, lo que permite que el código del lado del servidor envíe notificaciones asincrónicas a las aplicaciones web del lado del cliente.

Ejemplo de código

 public class MyHub : Hub { public async Task SendMessage(string user, string message) { await Clients.All.SendAsync("ReceiveMessage", user, message); } }

28. Configurar el almacenamiento en caché de respuestas

Concepto

El almacenamiento en caché de respuestas reduce la cantidad de solicitudes que un servidor debe manejar al almacenar una copia de los recursos solicitados previamente.

Ejemplo de código

 [HttpGet("{id}")] [ResponseCache(Duration = 60)] public IActionResult GetById(int id) { // Retrieve and return your resource }

29. Archivos estáticos

Concepto

Servir archivos estáticos (HTML, CSS, JavaScript, etc.) es esencial para respaldar aplicaciones front-end con una API web .NET.

Ejemplo de código

 app.UseStaticFiles(); // Enable static file serving

30. Patrón de opciones y configuración avanzada

Concepto

El patrón de opciones utiliza clases para representar grupos de configuraciones relacionadas. Usando IOptions<T>, puede acceder a estas configuraciones en cualquier lugar de su aplicación.

Ejemplo de código

 public class MySettings { public string Setting1 { get; set; } // Other settings } builder.Services.Configure<MySettings>(builder.Configuration.GetSection("MySettings")); public class MyService { private readonly MySettings _settings; public MyService(IOptions<MySettings> settings) { _settings = settings.Value; } // Use _settings.Setting1 }

31. Middleware personalizado

Concepto

El middleware es un software que se ensambla en una canalización de aplicaciones para manejar solicitudes y respuestas. Se puede crear middleware personalizado para realizar tareas específicas.

Ejemplo de código

 public class MyCustomMiddleware { private readonly RequestDelegate _next; public MyCustomMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext httpContext) { // Pre-processing logic here await _next(httpContext); // Call the next middleware in the pipeline // Post-processing logic here } } // Extension method for easy middleware registration public static class MyCustomMiddlewareExtensions { public static IApplicationBuilder UseMyCustomMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<MyCustomMiddleware>(); } }

32. Limitación de tasa

Concepto

La limitación de velocidad protege su API del uso excesivo al limitar la frecuencia con la que un usuario puede realizar solicitudes dentro de un período de tiempo determinado.

Ejemplo de código

 // Assume using a third-party library like AspNetCoreRateLimit builder.Services.AddInMemoryRateLimiting(); builder.Services.Configure<IpRateLimitOptions>(options => { options.GeneralRules = new List<RateLimitRule> { new RateLimitRule { Endpoint = "*", Limit = 100, Period = "1h" } }; });

33. Autenticación de claves API

Concepto

Las claves API son una forma sencilla de autenticar y autorizar llamadas API. Se pasan del cliente al servidor en la cadena de consulta o en el encabezado.

Ejemplo de código

 public class ApiKeyMiddleware { private readonly RequestDelegate _next; private const string APIKEYNAME = "x-api-key"; public ApiKeyMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { if (!context.Request.Headers.TryGetValue(APIKEYNAME, out var extractedApiKey)) { context.Response.StatusCode = 401; await context.Response.WriteAsync("API Key was not provided."); return; } // Validate the extracted API Key here... await _next(context); } }

34. Almacenamiento en caché de resultados

Concepto

El almacenamiento en caché de resultados le permite almacenar la respuesta a una solicitud. Las solicitudes posteriores se pueden atender desde la memoria caché, lo que mejora significativamente el rendimiento.

Ejemplo de código

 [HttpGet] [ResponseCache(Duration = 120, Location = ResponseCacheLocation.Client, NoStore = false)] public IActionResult Get() { // Your logic here }

35. Tareas en segundo plano

Concepto

Las tareas en segundo plano permiten que las operaciones se ejecuten en segundo plano, independientemente de las solicitudes de los usuarios, como enviar correos electrónicos o procesar trabajos de larga duración.

Ejemplo de código

 public class MyBackgroundService : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { // Your background task logic here await Task.Delay(TimeSpan.FromHours(1), stoppingToken); } } }

36. WebSockets

Concepto

WebSockets proporciona un canal de comunicación full-duplex a través de una única conexión de larga duración, ideal para aplicaciones en tiempo real.

Ejemplo de código

 app.UseWebSockets(); app.Use(async (context, next) => { if (context.WebSockets.IsWebSocketRequest) { WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(); // Handle the WebSocket request here } else { await next(); } });

37. Solicitar localización

Concepto

La localización de solicitudes proporciona una forma de localizar contenido para diferentes culturas e idiomas, según la información de la solicitud.

Ejemplo de código

 var supportedCultures = new[] { "en-US", "fr-FR" }; var localizationOptions = new RequestLocalizationOptions() .SetDefaultCulture(supportedCultures[0]) .AddSupportedCultures(supportedCultures) .AddSupportedUICultures(supportedCultures); app.UseRequestLocalization(localizationOptions);

38. Integración con GraphQL

Concepto

GraphQL es un lenguaje de consulta para API. La integración de una API web .NET con GraphQL permite una recuperación de datos más eficiente.

Ejemplo de código

 // Assume using a library like HotChocolate builder.Services .AddGraphQLServer() .AddQueryType<Query>(); app.MapGraphQL();

39. Monitoreo y Telemetría

Concepto

La supervisión y la telemetría implican recopilar, analizar y actuar sobre datos sobre el rendimiento y el uso de su aplicación.

Ejemplo de código

 // Assume using Application Insights builder.Services.AddApplicationInsightsTelemetry("YOUR_INSTRUMENTATION_KEY");

40. Hubs SignalR y comunicación en tiempo real

Concepto

SignalR es una biblioteca que simplifica la adición de funcionalidad web en tiempo real a las aplicaciones. La funcionalidad web en tiempo real es la capacidad de hacer que el código del servidor envíe contenido a los clientes conectados instantáneamente, sin necesidad de que el servidor espere a que un cliente solicite nuevos datos. SignalR es perfecto para desarrollar aplicaciones de chat, paneles de control en tiempo real y aplicaciones web más interactivas.

Ejemplo de código

 public class ChatHub : Hub { public async Task SendMessage(string user, string message) { // Call the broadcastMessage method to update clients. await Clients.All.SendAsync("broadcastMessage", user, message); } } // Startup or Program.cs app.MapHub<ChatHub>("/chathub");

Integración en Program.cs:

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // Other configurations... app.UseEndpoints(endpoints => { endpoints.MapHub<ChatHub>("/chathub"); }); }

41. Núcleo del marco de entidad avanzado: relaciones

Concepto

Entity Framework Core permite el mapeo de relaciones complejas entre entidades, como uno a uno, uno a muchos y muchos a muchos.

Ejemplo de código

 public class Author { public int AuthorId { get; set; } public string Name { get; set; } public ICollection<Book> Books { get; set; } } public class Book { public int BookId { get; set; } public string Title { get; set; } public int AuthorId { get; set; } public Author Author { get; set; } }

42. Atributos de validación personalizados

Concepto

Los atributos de validación personalizados le permiten definir su lógica de validación para modelos de datos, ampliando los atributos de validación integrados.

Ejemplo de código

 public class MyCustomValidationAttribute : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { // Your custom validation logic here if (value is int intValue && intValue > 0) { return ValidationResult.Success; } return new ValidationResult("Value must be positive"); } } public class MyModel { [MyCustomValidationAttribute] public int MyProperty { get; set; } }

43. Escenarios de configuración avanzada

Concepto

El patrón de opciones de .NET admite escenarios de configuración complejos, incluidos objetos anidados, listas y validación.

Ejemplo de código

 public class MyOptions { public MyNestedOptions Nested { get; set; } public List<string> Items { get; set; } } public class MyNestedOptions { public string Key { get; set; } } // In Program.cs or Startup.cs builder.Services.Configure<MyOptions>(builder.Configuration.GetSection("MyOptions"));

44. Monitoreo y elaboración de perfiles del desempeño

Concepto

Monitorear y crear perfiles de una aplicación puede identificar cuellos de botella e ineficiencias, esenciales para optimizar el rendimiento.

Ejemplo de código

 app.UseMiniProfiler();

45. Documentación API con Swagger y comentarios XML

Concepto

Mejore la documentación de su API integrando comentarios XML en su interfaz de usuario Swagger, brindando una experiencia más rica para los desarrolladores que consumen su API.

Ejemplo de código

 builder.Services.AddSwaggerGen(c => { var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); });

46. Globalización y localización

Concepto

La globalización y la localización permiten que su aplicación admita múltiples idiomas y culturas, haciéndola accesible a una audiencia global.

Ejemplo de código

 builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); app.UseRequestLocalization(app.Services.GetRequiredService<IOptions<RequestLocalizationOptions>>().Value);

47. Encabezados de seguridad

Concepto

Mejorar la seguridad de su aplicación web agregando varios encabezados HTTP puede protegerla contra ataques y vulnerabilidades comunes.

Ejemplo de código

 app.UseHsts(); app.UseXContentTypeOptions(); app.UseReferrerPolicy(opts => opts.NoReferrer()); app.UseXXssProtection(options => options.EnabledWithBlockMode()); app.UseXfo(options => options.Deny());

48. Banderas de funciones

Concepto

Los indicadores de funciones le permiten activar y desactivar funciones de su aplicación sin implementar código nuevo, lo que facilita las pruebas y las implementaciones.

Ejemplo de código

 // Using a library like Microsoft.FeatureManagement builder.Services.AddFeatureManagement();

49. Integración de Blazor

Concepto

Blazor le permite crear interfaces de usuario web interactivas utilizando C# en lugar de JavaScript. La integración de Blazor con Web API proporciona una experiencia de desarrollo completa y perfecta.

Ejemplo de código

 // In a Blazor Server app @code { private IEnumerable<WeatherForecast> forecasts; protected override async Task OnInitializedAsync() { forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast"); } }

50. Middleware avanzado para la compresión de respuestas

Concepto

La compresión de respuestas puede reducir el tamaño de las respuestas de su API, mejorando los tiempos de carga para los clientes en redes lentas.

Ejemplo de código

 builder.Services.AddResponseCompression(options => { options.Providers.Add<GzipCompressionProvider>(); options.EnableForHttps = true; }); app.UseResponseCompression();

Programación C#🚀

¡Gracias por ser parte de la comunidad C#! Antes de que te vayas:

Si ha llegado hasta aquí, muestre su agradecimiento con una palmada y siga al autor. 👏️️

Síguenos: X | LinkedIn | Dev.to | Hashnodo | Boletín | tumblr

Visita nuestras otras plataformas: GitHub | Instagram | Tiktok | Quora | diario.dev


También publicado aquí