Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Full-Stack-Web-Applications with Angular, Nx an...

Full-Stack-Web-Applications with Angular, Nx and .NET

Developing modern distributed systems with a front and back end is no longer an easy task given the wide range of options available today. In this session, Fabian Gosebrink and Steven Giesel will show how to develop a user-friendly and well-structured frontend with the help of Angular and how to provide a clean REST interface with .NET Core. Using the latest Angular features, such as standalone components and a structured architecture with Nx, a maintainable and scalable application is created on the client that communicates with the backend. The backend is also developed from scratch in this session with .NET Core to make the data available using a REST interface. Live updates with SignalR also offer the option of informing the client about events without having to manually reload the page. After this session, you will have a comprehensive impression of how to develop frontends with the latest Angular and Nx as well as backends with .NET Core so that nothing stands in the way of your next projects with Angular and .NET Core.

Fabian Gosebrink

September 20, 2024
Tweet

More Decks by Fabian Gosebrink

Other Decks in Technology

Transcript

  1. var builder = WebApplication.CreateBuilder(args); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build();

    if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.MapGet("/hello-world", () => new Greeting("Hallo Basta!")) .WithName("HelloWorld") .WithOpenApi(); app.Run(); record Greeting(string Message); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
  2. var builder = WebApplication.CreateBuilder(args); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build();

    if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.MapGet("/hello-world", () => new Greeting("Hallo Basta!")) .WithName("HelloWorld") .WithOpenApi(); app.Run(); record Greeting(string Message); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 app.MapGet("/hello-world", () => new Greeting("Hallo Basta!")) var builder = WebApplication.CreateBuilder(args); 1 2 builder.Services.AddEndpointsApiExplorer(); 3 builder.Services.AddSwaggerGen(); 4 5 var app = builder.Build(); 6 7 if (app.Environment.IsDevelopment()) 8 { 9 app.UseSwagger(); 10 app.UseSwaggerUI(); 11 } 12 13 app.UseHttpsRedirection(); 14 15 16 .WithName("HelloWorld") 17 .WithOpenApi(); 18 19 app.Run(); 20 21 record Greeting(string Message); 22
  3. var builder = WebApplication.CreateBuilder(args); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build();

    if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.MapGet("/hello-world", () => new Greeting("Hallo Basta!")) .WithName("HelloWorld") .WithOpenApi(); app.Run(); record Greeting(string Message); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 app.MapGet("/hello-world", () => new Greeting("Hallo Basta!")) var builder = WebApplication.CreateBuilder(args); 1 2 builder.Services.AddEndpointsApiExplorer(); 3 builder.Services.AddSwaggerGen(); 4 5 var app = builder.Build(); 6 7 if (app.Environment.IsDevelopment()) 8 { 9 app.UseSwagger(); 10 app.UseSwaggerUI(); 11 } 12 13 app.UseHttpsRedirection(); 14 15 16 .WithName("HelloWorld") 17 .WithOpenApi(); 18 19 app.Run(); 20 21 record Greeting(string Message); 22 builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var builder = WebApplication.CreateBuilder(args); 1 2 3 4 5 var app = builder.Build(); 6 7 if (app.Environment.IsDevelopment()) 8 { 9 app.UseSwagger(); 10 app.UseSwaggerUI(); 11 } 12 13 app.UseHttpsRedirection(); 14 15 app.MapGet("/hello-world", () => new Greeting("Hallo Basta!")) 16 .WithName("HelloWorld") 17 .WithOpenApi(); 18 19 app.Run(); 20 21 record Greeting(string Message); 22
  4. var builder = WebApplication.CreateBuilder(args); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build();

    if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.MapGet("/hello-world", () => new Greeting("Hallo Basta!")) .WithName("HelloWorld") .WithOpenApi(); app.Run(); record Greeting(string Message); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 app.MapGet("/hello-world", () => new Greeting("Hallo Basta!")) var builder = WebApplication.CreateBuilder(args); 1 2 builder.Services.AddEndpointsApiExplorer(); 3 builder.Services.AddSwaggerGen(); 4 5 var app = builder.Build(); 6 7 if (app.Environment.IsDevelopment()) 8 { 9 app.UseSwagger(); 10 app.UseSwaggerUI(); 11 } 12 13 app.UseHttpsRedirection(); 14 15 16 .WithName("HelloWorld") 17 .WithOpenApi(); 18 19 app.Run(); 20 21 record Greeting(string Message); 22 builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var builder = WebApplication.CreateBuilder(args); 1 2 3 4 5 var app = builder.Build(); 6 7 if (app.Environment.IsDevelopment()) 8 { 9 app.UseSwagger(); 10 app.UseSwaggerUI(); 11 } 12 13 app.UseHttpsRedirection(); 14 15 app.MapGet("/hello-world", () => new Greeting("Hallo Basta!")) 16 .WithName("HelloWorld") 17 .WithOpenApi(); 18 19 app.Run(); 20 21 record Greeting(string Message); 22 builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); app.UseSwagger(); app.UseSwaggerUI(); .WithName("HelloWorld") .WithOpenApi(); var builder = WebApplication.CreateBuilder(args); 1 2 3 4 5 var app = builder.Build(); 6 7 if (app.Environment.IsDevelopment()) 8 { 9 10 11 } 12 13 app.UseHttpsRedirection(); 14 15 app.MapGet("/hello-world", () => new Greeting("Hallo Basta!")) 16 17 18 19 app.Run(); 20 21 record Greeting(string Message); 22
  5. builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); app.UseSwagger(); app.UseSwaggerUI(); .WithName("HelloWorld") .WithOpenApi(); var builder = WebApplication.CreateBuilder(args);

    1 2 3 4 5 var app = builder.Build(); 6 7 if (app.Environment.IsDevelopment()) 8 { 9 10 11 } 12 13 app.UseHttpsRedirection(); 14 15 app.MapGet("/hello-world", () => new Greeting("Hallo Basta!")) 16 17 18 19 app.Run(); 20 21 record Greeting(string Message); 22
  6. builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); app.UseSwagger(); app.UseSwaggerUI(); .WithName("HelloWorld") .WithOpenApi(); var builder = WebApplication.CreateBuilder(args);

    1 2 3 4 5 var app = builder.Build(); 6 7 if (app.Environment.IsDevelopment()) 8 { 9 10 11 } 12 13 app.UseHttpsRedirection(); 14 15 app.MapGet("/hello-world", () => new Greeting("Hallo Basta!")) 16 17 18 19 app.Run(); 20 21 record Greeting(string Message); 22
  7. app.MapGet("/api/user/", () => { }) .WithOpenApi() .WithName("GetUser"); userGroup.MapPost("/api/user/", (CreateUserDto dto)

    => { }) .WithOpenApi() .WithName("CreateUser"); userGroup.MapDelete("/api/user/", (DeleteUserDto dto) => { }) .WithOpenApi() .WithName("DeleteUser"); 1 2 3 4 5 6 7 8 9 10 11
  8. // User Controller var userGroup = app.MapGroup("/api/user") .WithOpenApi(); userGroup.MapGet("/", ()

    => { }) .WithName("GetUser"); userGroup.MapPost("/", (CreateUserDto dto) => { }) .WithName("CreateUser"); userGroup.MapDelete("/", (DeleteUserDto dto) => { }) .WithName("DeleteUser"); 1 2 3 4 5 6 7 8 9 10 11 12
  9. public static class UserController { public static void UseUserController(this IEndpointRouteBuilder

    app) { var userGroup = app .MapGroup("/api/user") .WithOpenApi(); userGroup .MapGet("/", () => { }) .WithName("GetUser"); userGroup .MapPost("/", (CreateUserDto dto) => { }) .WithName("CreateUser"); userGroup .MapDelete("/", (DeleteUserDto dto) => { }) .WithName("DeleteUser"); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  10. public static class UserController { public static void UseUserController(this IEndpointRouteBuilder

    app) { var userGroup = app .MapGroup("/api/user") .WithOpenApi(); userGroup .MapGet("/", () => { }) .WithName("GetUser"); userGroup .MapPost("/", (CreateUserDto dto) => { }) .WithName("CreateUser"); userGroup .MapDelete("/", (DeleteUserDto dto) => { }) .WithName("DeleteUser"); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 app.UseUserController(); // Configure the HTTP request pipeline. 1 app.UseSwagger(); 2 app.UseSwaggerUI(); 3 4 // Now we have a very convient way 5 // of defining our own endpoints 6 7
  11. ([AsParameters]GreetingRequest request, record GreetingRequest([FromQuery]string Name); var builder = WebApplication.CreateBuilder(args); 1

    2 builder.Services.AddScoped<GreetingService>(); 3 4 var app = builder.Build(); 5 6 // ... 7 8 app.MapGet("/greet", 9 10 GreetingService service) 11 => service.GetGreeting(request.Name)); 12 13 14 app.Run(); 15 16 public class GreetingService 17 { 18 public string GetGreeting(string name) => $"Hello {name}!"; 19 } 20
  12. ([AsParameters]GreetingRequest request, record GreetingRequest([FromQuery]string Name); var builder = WebApplication.CreateBuilder(args); 1

    2 builder.Services.AddScoped<GreetingService>(); 3 4 var app = builder.Build(); 5 6 // ... 7 8 app.MapGet("/greet", 9 10 GreetingService service) 11 => service.GetGreeting(request.Name)); 12 13 14 app.Run(); 15 16 public class GreetingService 17 { 18 public string GetGreeting(string name) => $"Hello {name}!"; 19 } 20 builder.Services.AddScoped<GreetingService>(); GreetingService service) public class GreetingService { public string GetGreeting(string name) => $"Hello {name}!"; } var builder = WebApplication.CreateBuilder(args); 1 2 3 4 var app = builder.Build(); 5 6 // ... 7 8 app.MapGet("/greet", 9 ([AsParameters]GreetingRequest request, 10 11 => service.GetGreeting(request.Name)); 12 13 14 app.Run(); 15 record GreetingRequest([FromQuery]string Name); 16 17 18 19 20
  13. ([AsParameters]GreetingRequest request, record GreetingRequest([FromQuery]string Name); var builder = WebApplication.CreateBuilder(args); 1

    2 builder.Services.AddScoped<GreetingService>(); 3 4 var app = builder.Build(); 5 6 // ... 7 8 app.MapGet("/greet", 9 10 GreetingService service) 11 => service.GetGreeting(request.Name)); 12 13 14 app.Run(); 15 16 public class GreetingService 17 { 18 public string GetGreeting(string name) => $"Hello {name}!"; 19 } 20 builder.Services.AddScoped<GreetingService>(); GreetingService service) public class GreetingService { public string GetGreeting(string name) => $"Hello {name}!"; } var builder = WebApplication.CreateBuilder(args); 1 2 3 4 var app = builder.Build(); 5 6 // ... 7 8 app.MapGet("/greet", 9 ([AsParameters]GreetingRequest request, 10 11 => service.GetGreeting(request.Name)); 12 13 14 app.Run(); 15 record GreetingRequest([FromQuery]string Name); 16 17 18 19 20 app.MapGet("/greet", ([AsParameters]GreetingRequest request, GreetingService service) => service.GetGreeting(request.Name)); var builder = WebApplication.CreateBuilder(args); 1 2 builder.Services.AddScoped<GreetingService>(); 3 4 var app = builder.Build(); 5 6 // ... 7 8 9 10 11 12 13 14 app.Run(); 15 record GreetingRequest([FromQuery]string Name); 16 public class GreetingService 17 { 18 public string GetGreeting(string name) => $"Hello {name}!"; 19 } 20
  14. ([AsParameters]GreetingRequest request, record GreetingRequest([FromQuery]string Name); var builder = WebApplication.CreateBuilder(args); 1

    2 builder.Services.AddScoped<GreetingService>(); 3 4 var app = builder.Build(); 5 6 // ... 7 8 app.MapGet("/greet", 9 10 GreetingService service) 11 => service.GetGreeting(request.Name)); 12 13 14 app.Run(); 15 16 public class GreetingService 17 { 18 public string GetGreeting(string name) => $"Hello {name}!"; 19 } 20 builder.Services.AddScoped<GreetingService>(); GreetingService service) public class GreetingService { public string GetGreeting(string name) => $"Hello {name}!"; } var builder = WebApplication.CreateBuilder(args); 1 2 3 4 var app = builder.Build(); 5 6 // ... 7 8 app.MapGet("/greet", 9 ([AsParameters]GreetingRequest request, 10 11 => service.GetGreeting(request.Name)); 12 13 14 app.Run(); 15 record GreetingRequest([FromQuery]string Name); 16 17 18 19 20 app.MapGet("/greet", ([AsParameters]GreetingRequest request, GreetingService service) => service.GetGreeting(request.Name)); var builder = WebApplication.CreateBuilder(args); 1 2 builder.Services.AddScoped<GreetingService>(); 3 4 var app = builder.Build(); 5 6 // ... 7 8 9 10 11 12 13 14 app.Run(); 15 record GreetingRequest([FromQuery]string Name); 16 public class GreetingService 17 { 18 public string GetGreeting(string name) => $"Hello {name}!"; 19 } 20 var builder = WebApplication.CreateBuilder(args); builder.Services.AddScoped<GreetingService>(); var app = builder.Build(); // ... app.MapGet("/greet", ([AsParameters]GreetingRequest request, GreetingService service) => service.GetGreeting(request.Name)); app.Run(); record GreetingRequest([FromQuery]string Name); public class GreetingService { public string GetGreeting(string name) => $"Hello {name}!"; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  15. builder.Services.AddDbContext<AppDbContext>(optionsBuilder => { optionsBuilder.UseSqlite("Data Source=app.db"); }); // .. app.RegisterExpenseEndpoints(); app.UseExceptionHandler();

    app.Use(async (context, next) => { var logger = app.Logger; var displayUrl = context.Request.GetDisplayUrl(); logger.LogDebug("Before Request with Uri '{Uri}'", displayUrl); await next(context); logger.LogDebug("After Request with Uri '{Uri}'", displayUrl); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  16. builder.Services.AddDbContext<AppDbContext>(optionsBuilder => { optionsBuilder.UseSqlite("Data Source=app.db"); }); // .. app.RegisterExpenseEndpoints(); app.UseExceptionHandler();

    app.Use(async (context, next) => { var logger = app.Logger; var displayUrl = context.Request.GetDisplayUrl(); logger.LogDebug("Before Request with Uri '{Uri}'", displayUrl); await next(context); logger.LogDebug("After Request with Uri '{Uri}'", displayUrl); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 builder.Services.AddDbContext<AppDbContext>(optionsBuilder => { optionsBuilder.UseSqlite("Data Source=app.db"); 1 2 3 }); 4 5 // .. 6 7 app.RegisterExpenseEndpoints(); 8 9 10 app.UseExceptionHandler(); 11 12 app.Use(async (context, next) => 13 { 14 var logger = app.Logger; 15 var displayUrl = context.Request.GetDisplayUrl(); 16 logger.LogDebug("Before Request with Uri '{Uri}'", displayUrl); 17 await next(context); 18 logger.LogDebug("After Request with Uri '{Uri}'", displayUrl); 19 }); 20
  17. builder.Services.AddDbContext<AppDbContext>(optionsBuilder => { optionsBuilder.UseSqlite("Data Source=app.db"); }); // .. app.RegisterExpenseEndpoints(); app.UseExceptionHandler();

    app.Use(async (context, next) => { var logger = app.Logger; var displayUrl = context.Request.GetDisplayUrl(); logger.LogDebug("Before Request with Uri '{Uri}'", displayUrl); await next(context); logger.LogDebug("After Request with Uri '{Uri}'", displayUrl); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 builder.Services.AddDbContext<AppDbContext>(optionsBuilder => { optionsBuilder.UseSqlite("Data Source=app.db"); 1 2 3 }); 4 5 // .. 6 7 app.RegisterExpenseEndpoints(); 8 9 10 app.UseExceptionHandler(); 11 12 app.Use(async (context, next) => 13 { 14 var logger = app.Logger; 15 var displayUrl = context.Request.GetDisplayUrl(); 16 logger.LogDebug("Before Request with Uri '{Uri}'", displayUrl); 17 await next(context); 18 logger.LogDebug("After Request with Uri '{Uri}'", displayUrl); 19 }); 20 app.UseExceptionHandler(); builder.Services.AddDbContext<AppDbContext>(optionsBuilder => 1 { 2 optionsBuilder.UseSqlite("Data Source=app.db"); 3 }); 4 5 // .. 6 7 app.RegisterExpenseEndpoints(); 8 9 10 11 12 app.Use(async (context, next) => 13 { 14 var logger = app.Logger; 15 var displayUrl = context.Request.GetDisplayUrl(); 16 logger.LogDebug("Before Request with Uri '{Uri}'", displayUrl); 17 await next(context); 18 logger.LogDebug("After Request with Uri '{Uri}'", displayUrl); 19 }); 20
  18. builder.Services.AddDbContext<AppDbContext>(optionsBuilder => { optionsBuilder.UseSqlite("Data Source=app.db"); }); // .. app.RegisterExpenseEndpoints(); app.UseExceptionHandler();

    app.Use(async (context, next) => { var logger = app.Logger; var displayUrl = context.Request.GetDisplayUrl(); logger.LogDebug("Before Request with Uri '{Uri}'", displayUrl); await next(context); logger.LogDebug("After Request with Uri '{Uri}'", displayUrl); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 builder.Services.AddDbContext<AppDbContext>(optionsBuilder => { optionsBuilder.UseSqlite("Data Source=app.db"); 1 2 3 }); 4 5 // .. 6 7 app.RegisterExpenseEndpoints(); 8 9 10 app.UseExceptionHandler(); 11 12 app.Use(async (context, next) => 13 { 14 var logger = app.Logger; 15 var displayUrl = context.Request.GetDisplayUrl(); 16 logger.LogDebug("Before Request with Uri '{Uri}'", displayUrl); 17 await next(context); 18 logger.LogDebug("After Request with Uri '{Uri}'", displayUrl); 19 }); 20 app.UseExceptionHandler(); builder.Services.AddDbContext<AppDbContext>(optionsBuilder => 1 { 2 optionsBuilder.UseSqlite("Data Source=app.db"); 3 }); 4 5 // .. 6 7 app.RegisterExpenseEndpoints(); 8 9 10 11 12 app.Use(async (context, next) => 13 { 14 var logger = app.Logger; 15 var displayUrl = context.Request.GetDisplayUrl(); 16 logger.LogDebug("Before Request with Uri '{Uri}'", displayUrl); 17 await next(context); 18 logger.LogDebug("After Request with Uri '{Uri}'", displayUrl); 19 }); 20 app.Use(async (context, next) => { var logger = app.Logger; var displayUrl = context.Request.GetDisplayUrl(); logger.LogDebug("Before Request with Uri '{Uri}'", displayUrl); await next(context); logger.LogDebug("After Request with Uri '{Uri}'", displayUrl); }); builder.Services.AddDbContext<AppDbContext>(optionsBuilder => 1 { 2 optionsBuilder.UseSqlite("Data Source=app.db"); 3 }); 4 5 // .. 6 7 app.RegisterExpenseEndpoints(); 8 9 10 app.UseExceptionHandler(); 11 12 13 14 15 16 17 18 19 20
  19. builder.Services.AddDbContext<AppDbContext>(optionsBuilder => { optionsBuilder.UseSqlite("Data Source=app.db"); }); // .. app.RegisterExpenseEndpoints(); app.UseExceptionHandler();

    app.Use(async (context, next) => { var logger = app.Logger; var displayUrl = context.Request.GetDisplayUrl(); logger.LogDebug("Before Request with Uri '{Uri}'", displayUrl); await next(context); logger.LogDebug("After Request with Uri '{Uri}'", displayUrl); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 builder.Services.AddDbContext<AppDbContext>(optionsBuilder => { optionsBuilder.UseSqlite("Data Source=app.db"); 1 2 3 }); 4 5 // .. 6 7 app.RegisterExpenseEndpoints(); 8 9 10 app.UseExceptionHandler(); 11 12 app.Use(async (context, next) => 13 { 14 var logger = app.Logger; 15 var displayUrl = context.Request.GetDisplayUrl(); 16 logger.LogDebug("Before Request with Uri '{Uri}'", displayUrl); 17 await next(context); 18 logger.LogDebug("After Request with Uri '{Uri}'", displayUrl); 19 }); 20 app.UseExceptionHandler(); builder.Services.AddDbContext<AppDbContext>(optionsBuilder => 1 { 2 optionsBuilder.UseSqlite("Data Source=app.db"); 3 }); 4 5 // .. 6 7 app.RegisterExpenseEndpoints(); 8 9 10 11 12 app.Use(async (context, next) => 13 { 14 var logger = app.Logger; 15 var displayUrl = context.Request.GetDisplayUrl(); 16 logger.LogDebug("Before Request with Uri '{Uri}'", displayUrl); 17 await next(context); 18 logger.LogDebug("After Request with Uri '{Uri}'", displayUrl); 19 }); 20 app.Use(async (context, next) => { var logger = app.Logger; var displayUrl = context.Request.GetDisplayUrl(); logger.LogDebug("Before Request with Uri '{Uri}'", displayUrl); await next(context); logger.LogDebug("After Request with Uri '{Uri}'", displayUrl); }); builder.Services.AddDbContext<AppDbContext>(optionsBuilder => 1 { 2 optionsBuilder.UseSqlite("Data Source=app.db"); 3 }); 4 5 // .. 6 7 app.RegisterExpenseEndpoints(); 8 9 10 app.UseExceptionHandler(); 11 12 13 14 15 16 17 18 19 20 app.RegisterExpenseEndpoints(); builder.Services.AddDbContext<AppDbContext>(optionsBuilder => 1 { 2 optionsBuilder.UseSqlite("Data Source=app.db"); 3 }); 4 5 // .. 6 7 8 9 10 app.UseExceptionHandler(); 11 12 app.Use(async (context, next) => 13 { 14 var logger = app.Logger; 15 var displayUrl = context.Request.GetDisplayUrl(); 16 logger.LogDebug("Before Request with Uri '{Uri}'", displayUrl); 17 await next(context); 18 logger.LogDebug("After Request with Uri '{Uri}'", displayUrl); 19 }); 20
  20. app.RegisterExpenseEndpoints(); public static void RegisterExpenseEndpoints(this IEndpointRouteBuilder endpoint) { var group

    = endpoint.MapGroup("/api/expenses"); group.MapGet("/", async (AppDbContext dbContext, int? page, int? pageSize) => { page ??= 0; pageSize ??= int.MaxValue; return await dbContext .Expenses .OrderBy(b => b.Id) .Skip(page.Value) .Take(pageSize.Value) .AsNoTracking() .ToListAsync(); }) .WithDescription("Retrieves all expenses."); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
  21. group.MapGet("/", async (ExpenseRepository repository, int? page, int? pageSize) => public

    static void RegisterExpenseEndpoints(this IEndpointRouteBuilder endpoint) 1 { 2 var group = endpoint.MapGroup("/api/expenses"); 3 4 5 { 6 page ??= 0; 7 pageSize ??= int.MaxValue; 8 9 return await repository.GetAllAsync(page, pageSize); 10 }) 11 .WithDescription("Retrieves all expenses."); 12 } 13 app.RegisterExpenseEndpoints();
  22. group.MapGet("/", async (ExpenseRepository repository, int? page, int? pageSize) => public

    static void RegisterExpenseEndpoints(this IEndpointRouteBuilder endpoint) 1 { 2 var group = endpoint.MapGroup("/api/expenses"); 3 4 5 { 6 page ??= 0; 7 pageSize ??= int.MaxValue; 8 9 return await repository.GetAllAsync(page, pageSize); 10 }) 11 .WithDescription("Retrieves all expenses."); 12 } 13 return await repository.GetAllAsync(page, pageSize); public static void RegisterExpenseEndpoints(this IEndpointRouteBuilder endpoint) 1 { 2 var group = endpoint.MapGroup("/api/expenses"); 3 4 group.MapGet("/", async (ExpenseRepository repository, int? page, int? pageSize) => 5 { 6 page ??= 0; 7 pageSize ??= int.MaxValue; 8 9 10 }) 11 .WithDescription("Retrieves all expenses."); 12 } 13 app.RegisterExpenseEndpoints();
  23. app.RegisterExpenseEndpoints(); return await repository.GetAllAsync(page, pageSize); public class ExpenseRepository { private

    readonly AppDbContext _dbContext; public ExpenseRepository(AppDbContext dbContext) => _dbContext = dbContext; public async Task<IEnumerable<Expense>> GetAllExpenses( int page, int pageSize) { return await _dbContext .Expenses .OrderBy(b => b.Id) .Skip(page) .Take(pageSize) .AsNoTracking() .ToListAsync(); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  24. yarn add -D @nx-dotnet/core 1 2 nx g @nx-dotnet/core:init 3

    4 nx g @nx-dotnet/core:app ExpenseAPI \ 5 --directory=apps/ExpenseAPI \ 6 --test-template xunit 7 8 nx serve AppsExpenseAPI.ExpenseAPI 9
  25. yarn add -D @nx-dotnet/core 1 2 nx g @nx-dotnet/core:init 3

    4 nx g @nx-dotnet/core:app ExpenseAPI \ 5 --directory=apps/ExpenseAPI \ 6 --test-template xunit 7 8 nx serve AppsExpenseAPI.ExpenseAPI 9 nx g @nx-dotnet/core:init yarn add -D @nx-dotnet/core 1 2 3 4 nx g @nx-dotnet/core:app ExpenseAPI \ 5 --directory=apps/ExpenseAPI \ 6 --test-template xunit 7 8 nx serve AppsExpenseAPI.ExpenseAPI 9
  26. yarn add -D @nx-dotnet/core 1 2 nx g @nx-dotnet/core:init 3

    4 nx g @nx-dotnet/core:app ExpenseAPI \ 5 --directory=apps/ExpenseAPI \ 6 --test-template xunit 7 8 nx serve AppsExpenseAPI.ExpenseAPI 9 nx g @nx-dotnet/core:init yarn add -D @nx-dotnet/core 1 2 3 4 nx g @nx-dotnet/core:app ExpenseAPI \ 5 --directory=apps/ExpenseAPI \ 6 --test-template xunit 7 8 nx serve AppsExpenseAPI.ExpenseAPI 9 nx g @nx-dotnet/core:app ExpenseAPI \ --directory=apps/ExpenseAPI \ --test-template xunit yarn add -D @nx-dotnet/core 1 2 nx g @nx-dotnet/core:init 3 4 5 6 7 8 nx serve AppsExpenseAPI.ExpenseAPI 9
  27. yarn add -D @nx-dotnet/core 1 2 nx g @nx-dotnet/core:init 3

    4 nx g @nx-dotnet/core:app ExpenseAPI \ 5 --directory=apps/ExpenseAPI \ 6 --test-template xunit 7 8 nx serve AppsExpenseAPI.ExpenseAPI 9 nx g @nx-dotnet/core:init yarn add -D @nx-dotnet/core 1 2 3 4 nx g @nx-dotnet/core:app ExpenseAPI \ 5 --directory=apps/ExpenseAPI \ 6 --test-template xunit 7 8 nx serve AppsExpenseAPI.ExpenseAPI 9 nx g @nx-dotnet/core:app ExpenseAPI \ --directory=apps/ExpenseAPI \ --test-template xunit yarn add -D @nx-dotnet/core 1 2 nx g @nx-dotnet/core:init 3 4 5 6 7 8 nx serve AppsExpenseAPI.ExpenseAPI 9 nx serve AppsExpenseAPI.ExpenseAPI yarn add -D @nx-dotnet/core 1 2 nx g @nx-dotnet/core:init 3 4 nx g @nx-dotnet/core:app ExpenseAPI \ 5 --directory=apps/ExpenseAPI \ 6 --test-template xunit 7 8 9