c#
using Backend.Common;
using Backend.Common.Api.Extensions;
using Backend.Data;
using Backend.Data.Types;
using FluentValidation;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.EntityFrameworkCore;
namespace Backend.Posts.Endpoints;
public class UpdatePost : IEndpoint
{
public static void Map(IEndpointRouteBuilder app)
{
app
.MapPut("{id:guid}", Handle)
.RequireAuthorization()
.WithSummary("Updates an existing post")
.WithRequestValidation<Request>()
.WithEnsureUserOwnsEntity<Post, Request>(x => x.Id);
}
public record Request(
Guid Id,
string Title,
string Body,
Uri? CoverImageUrl);
public record Response(Guid Id, string Title, DateTime UpdatedAtUtc);
public class RequestValidator : AbstractValidator<Request>
{
public RequestValidator()
{
RuleFor(x => x.Id)
.NotEmpty()
.Must(x => Guid.TryParse(x.ToString(), out _))
.WithMessage("Invalid GUID format");
RuleFor(x => x.Title)
.NotEmpty()
.MaximumLength(200);
RuleFor(x => x.Body)
.NotEmpty();
}
}
private static async Task<Ok<Response>> Handle(
[AsParameters] Request request,
BlogDbContext dbContext,
CancellationToken cancellationToken)
{
var post = await dbContext.Posts
.FirstAsync(p => p.Id == request.Id, cancellationToken);
post.Title = request.Title;
post.Body = request.Body;
post.CoverImageUrl = request.CoverImageUrl;
post.UpdatedAtUtc = DateTime.UtcNow;
await dbContext.SaveChangesAsync(cancellationToken);
var response = new Response(post.Id, post.Title, post.UpdatedAtUtc ?? DateTime.UtcNow);
return TypedResults.Ok(response);
}
}