Skip to content

Commit

Permalink
Merge pull request #236 from meysamhadeli/feat/add-result-model-for-h…
Browse files Browse the repository at this point in the history
…andlers

feat: Add result model for handlers for better structure in vertical …
  • Loading branch information
meysamhadeli authored Mar 22, 2023
2 parents 1132780 + 6cb2563 commit 1e6f5b8
Show file tree
Hide file tree
Showing 51 changed files with 273 additions and 204 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ namespace Booking.Booking.Features.CreatingBook.Commands.V1;
using Models.ValueObjects;
using Passenger;

public record CreateBooking(long PassengerId, long FlightId, string Description) : ICommand<ulong>, IInternalCommand
public record CreateBooking(long PassengerId, long FlightId, string Description) : ICommand<CreateBookingResult>, IInternalCommand
{
public long Id { get; init; } = SnowFlakIdGenerator.NewId();
}

public record CreateBookingResult(ulong Id);

internal class CreateBookingValidator : AbstractValidator<CreateBooking>
{
public CreateBookingValidator()
Expand All @@ -27,7 +29,7 @@ public CreateBookingValidator()
}
}

internal class CreateBookingCommandHandler : ICommandHandler<CreateBooking, ulong>
internal class CreateBookingCommandHandler : ICommandHandler<CreateBooking, CreateBookingResult>
{
private readonly IEventStoreDBRepository<Models.Booking> _eventStoreDbRepository;
private readonly ICurrentUserProvider _currentUserProvider;
Expand All @@ -48,7 +50,7 @@ public CreateBookingCommandHandler(IEventStoreDBRepository<Models.Booking> event
_passengerGrpcServiceClient = passengerGrpcServiceClient;
}

public async Task<ulong> Handle(CreateBooking command, CancellationToken cancellationToken)
public async Task<CreateBookingResult> Handle(CreateBooking command, CancellationToken cancellationToken)
{
Guard.Against.Null(command, nameof(command));

Expand Down Expand Up @@ -90,6 +92,6 @@ await _flightGrpcServiceClient.ReserveSeatAsync(new ReserveSeatRequest
aggrigate,
cancellationToken);

return result;
return new CreateBookingResult(result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace Booking.Booking.Features.CreatingBook.Commands.V1;
using Swashbuckle.AspNetCore.Annotations;

public record CreateBookingRequestDto(long PassengerId, long FlightId, string Description);
public record CreateBookingResponseDto(ulong Id);

public class CreateBookingEndpoint : IMinimalEndpoint
{
Expand All @@ -25,7 +26,7 @@ public IEndpointRouteBuilder MapEndpoint(IEndpointRouteBuilder builder)
new SwaggerResponseAttribute(
StatusCodes.Status200OK,
"Booking Created",
typeof(ulong)))
typeof(CreateBookingResponseDto)))
.WithMetadata(
new SwaggerResponseAttribute(
StatusCodes.Status400BadRequest,
Expand All @@ -48,6 +49,8 @@ private async Task<IResult> CreateBooking(CreateBookingRequestDto request, IMedi

var result = await mediator.Send(command, cancellationToken);

return Results.Ok(result);
var response = new CreateBookingResponseDto(result.Id);

return Results.Ok(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public async Task should_create_booking_to_event_store_currectly()
var response = await Fixture.SendAsync(command);

// Assert
response.Should().BeGreaterOrEqualTo(0);
response?.Id.Should().BeGreaterOrEqualTo(0);

(await Fixture.WaitForPublishing<BookingCreated>()).Should().Be(true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ namespace Flight.Aircrafts.Features.CreatingAircraft.V1;
using MediatR;
using Microsoft.EntityFrameworkCore;

public record CreateAircraft(string Name, string Model, int ManufacturingYear) : ICommand<AircraftDto>, IInternalCommand
public record CreateAircraft(string Name, string Model, int ManufacturingYear) : ICommand<CreateAircraftResult>, IInternalCommand
{
public long Id { get; init; } = SnowFlakIdGenerator.NewId();
}

public record CreateAircraftResult(long Id);

internal class CreateAircraftValidator : AbstractValidator<CreateAircraft>
{
public CreateAircraftValidator()
Expand All @@ -30,18 +32,16 @@ public CreateAircraftValidator()
}
}

internal class CreateAircraftHandler : IRequestHandler<CreateAircraft, AircraftDto>
internal class CreateAircraftHandler : IRequestHandler<CreateAircraft, CreateAircraftResult>
{
private readonly FlightDbContext _flightDbContext;
private readonly IMapper _mapper;

public CreateAircraftHandler(IMapper mapper, FlightDbContext flightDbContext)
public CreateAircraftHandler(FlightDbContext flightDbContext)
{
_mapper = mapper;
_flightDbContext = flightDbContext;
}

public async Task<AircraftDto> Handle(CreateAircraft request, CancellationToken cancellationToken)
public async Task<CreateAircraftResult> Handle(CreateAircraft request, CancellationToken cancellationToken)
{
Guard.Against.Null(request, nameof(request));

Expand All @@ -54,10 +54,8 @@ public async Task<AircraftDto> Handle(CreateAircraft request, CancellationToken

var aircraftEntity = Aircraft.Create(request.Id, request.Name, request.Model, request.ManufacturingYear);

var newAircraft = await _flightDbContext.Aircraft.AddAsync(aircraftEntity, cancellationToken);

await _flightDbContext.SaveChangesAsync(cancellationToken);
var newAircraft = (await _flightDbContext.Aircraft.AddAsync(aircraftEntity, cancellationToken))?.Entity;

return _mapper.Map<AircraftDto>(newAircraft.Entity);
return new CreateAircraftResult(newAircraft.Id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace Flight.Aircrafts.Features.CreatingAircraft.V1;
using Swashbuckle.AspNetCore.Annotations;

public record CreateAircraftRequestDto(string Name, string Model, int ManufacturingYear);
public record CreateAircraftResponseDto(long Id);

public class CreateAircraftEndpoint : IMinimalEndpoint
{
Expand All @@ -28,7 +29,7 @@ public IEndpointRouteBuilder MapEndpoint(IEndpointRouteBuilder builder)
new SwaggerResponseAttribute(
StatusCodes.Status200OK,
"Aircraft Created",
typeof(AircraftDto)))
typeof(CreateAircraftResponseDto)))
.WithMetadata(
new SwaggerResponseAttribute(
StatusCodes.Status400BadRequest,
Expand All @@ -51,6 +52,8 @@ private async Task<IResult> CreateAircraft(CreateAircraftRequestDto request, IMe

var result = await mediator.Send(command, cancellationToken);

return Results.Ok(result);
var response = new CreateAircraftResponseDto(result.Id);

return Results.Ok(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ namespace Flight.Airports.Features.CreatingAirport.V1;
using MediatR;
using Microsoft.EntityFrameworkCore;

public record CreateAirport(string Name, string Address, string Code) : ICommand<AirportDto>, IInternalCommand
public record CreateAirport(string Name, string Address, string Code) : ICommand<CreateAirportResult>, IInternalCommand
{
public long Id { get; init; } = SnowFlakIdGenerator.NewId();
}

public record CreateAirportResult(long Id);

internal class CreateAirportValidator : AbstractValidator<CreateAirport>
{
public CreateAirportValidator()
Expand All @@ -30,18 +32,16 @@ public CreateAirportValidator()
}


internal class CreateAirportHandler : IRequestHandler<CreateAirport, AirportDto>
internal class CreateAirportHandler : IRequestHandler<CreateAirport, CreateAirportResult>
{
private readonly FlightDbContext _flightDbContext;
private readonly IMapper _mapper;

public CreateAirportHandler(IMapper mapper, FlightDbContext flightDbContext)
public CreateAirportHandler(FlightDbContext flightDbContext)
{
_mapper = mapper;
_flightDbContext = flightDbContext;
}

public async Task<AirportDto> Handle(CreateAirport request, CancellationToken cancellationToken)
public async Task<CreateAirportResult> Handle(CreateAirport request, CancellationToken cancellationToken)
{
Guard.Against.Null(request, nameof(request));

Expand All @@ -54,10 +54,8 @@ public async Task<AirportDto> Handle(CreateAirport request, CancellationToken ca

var airportEntity = Models.Airport.Create(request.Id, request.Name, request.Code, request.Address);

var newAirport = await _flightDbContext.Airports.AddAsync(airportEntity, cancellationToken);

await _flightDbContext.SaveChangesAsync(cancellationToken);
var newAirport = (await _flightDbContext.Airports.AddAsync(airportEntity, cancellationToken))?.Entity;

return _mapper.Map<AirportDto>(newAirport.Entity);
return new CreateAirportResult(newAirport.Id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace Flight.Airports.Features.CreatingAirport.V1;
using Swashbuckle.AspNetCore.Annotations;

public record CreateAirportRequestDto(string Name, string Address, string Code);
public record CreateAirportResponseDto(long Id);

public class CreateAirportEndpoint : IMinimalEndpoint
{
Expand All @@ -28,7 +29,7 @@ public IEndpointRouteBuilder MapEndpoint(IEndpointRouteBuilder builder)
new SwaggerResponseAttribute(
StatusCodes.Status200OK,
"Airport Created",
typeof(AirportDto)))
typeof(CreateAirportResponseDto)))
.WithMetadata(
new SwaggerResponseAttribute(
StatusCodes.Status400BadRequest,
Expand All @@ -51,6 +52,8 @@ private async Task<IResult> CreateAirport(CreateAirportRequestDto request, IMedi

var result = await mediator.Send(command, cancellationToken);

return Results.Ok(result);
var response = new CreateAirportResponseDto(result.Id);

return Results.Ok(response);
}
}
1 change: 0 additions & 1 deletion src/Services/Flight/src/Flight/Flights/Dtos/FlightDto.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using Flight.Flights.Models;

namespace Flight.Flights.Dtos;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ namespace Flight.Flights.Features.CreatingFlight.V1;

public record CreateFlight(string FlightNumber, long AircraftId, long DepartureAirportId,
DateTime DepartureDate, DateTime ArriveDate, long ArriveAirportId,
decimal DurationMinutes, DateTime FlightDate, Enums.FlightStatus Status, decimal Price) : ICommand<FlightDto>, IInternalCommand
decimal DurationMinutes, DateTime FlightDate, Enums.FlightStatus Status,
decimal Price) : ICommand<CreateFlightResult>, IInternalCommand
{
public long Id { get; init; } = SnowFlakIdGenerator.NewId();
}

public record CreateFlightResult(long Id);

internal class CreateFlightValidator : AbstractValidator<CreateFlight>
{
public CreateFlightValidator()
Expand All @@ -42,19 +45,16 @@ public CreateFlightValidator()
}
}

internal class CreateFlightHandler : ICommandHandler<CreateFlight, FlightDto>
internal class CreateFlightHandler : ICommandHandler<CreateFlight, CreateFlightResult>
{
private readonly FlightDbContext _flightDbContext;
private readonly IMapper _mapper;

public CreateFlightHandler(IMapper mapper,
FlightDbContext flightDbContext)
public CreateFlightHandler(FlightDbContext flightDbContext)
{
_mapper = mapper;
_flightDbContext = flightDbContext;
}

public async Task<FlightDto> Handle(CreateFlight request, CancellationToken cancellationToken)
public async Task<CreateFlightResult> Handle(CreateFlight request, CancellationToken cancellationToken)
{
Guard.Against.Null(request, nameof(request));

Expand All @@ -71,8 +71,8 @@ public async Task<FlightDto> Handle(CreateFlight request, CancellationToken canc
request.ArriveDate, request.ArriveAirportId, request.DurationMinutes, request.FlightDate, request.Status,
request.Price);

var newFlight = await _flightDbContext.Flights.AddAsync(flightEntity, cancellationToken);
var newFlight = (await _flightDbContext.Flights.AddAsync(flightEntity, cancellationToken))?.Entity;

return _mapper.Map<FlightDto>(newFlight.Entity);
return new CreateFlightResult(newFlight.Id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ namespace Flight.Flights.Features.CreatingFlight.V1;
using System.Threading;
using System.Threading.Tasks;
using BuildingBlocks.Web;
using Flight.Flights.Dtos;
using Hellang.Middleware.ProblemDetails;
using MapsterMapper;
using MediatR;
Expand All @@ -17,6 +16,8 @@ public record CreateFlightRequestDto(string FlightNumber, long AircraftId, long
DateTime DepartureDate, DateTime ArriveDate, long ArriveAirportId,
decimal DurationMinutes, DateTime FlightDate, Enums.FlightStatus Status, decimal Price);

public record CreateFlightResponseDto(long Id);

public class CreateFlightEndpoint : IMinimalEndpoint
{
public IEndpointRouteBuilder MapEndpoint(IEndpointRouteBuilder builder)
Expand All @@ -31,7 +32,7 @@ public IEndpointRouteBuilder MapEndpoint(IEndpointRouteBuilder builder)
new SwaggerResponseAttribute(
StatusCodes.Status201Created,
"Flight Created",
typeof(FlightDto)))
typeof(CreateFlightResponseDto)))
.WithMetadata(
new SwaggerResponseAttribute(
StatusCodes.Status400BadRequest,
Expand All @@ -54,6 +55,8 @@ private async Task<IResult> CreateFlight(CreateFlightRequestDto request, IMediat

var result = await mediator.Send(command, cancellationToken);

return Results.CreatedAtRoute("GetFlightById", new {id = result.Id}, result);
var response = new CreateFlightResponseDto(result.Id);

return Results.CreatedAtRoute("GetFlightById", new {id = result.Id}, response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
using MapsterMapper;
using Microsoft.EntityFrameworkCore;

public record DeleteFlight(long Id) : ICommand<FlightDto>, IInternalCommand;
public record DeleteFlight(long Id) : ICommand<DeleteFlightResult>, IInternalCommand;

public record DeleteFlightResult(long Id);

internal class DeleteFlightValidator : AbstractValidator<DeleteFlight>
{
Expand All @@ -22,18 +24,16 @@ public DeleteFlightValidator()
}
}

internal class DeleteFlightHandler : ICommandHandler<DeleteFlight, FlightDto>
internal class DeleteFlightHandler : ICommandHandler<DeleteFlight, DeleteFlightResult>
{
private readonly FlightDbContext _flightDbContext;
private readonly IMapper _mapper;

public DeleteFlightHandler(IMapper mapper, FlightDbContext flightDbContext)
public DeleteFlightHandler(FlightDbContext flightDbContext)
{
_mapper = mapper;
_flightDbContext = flightDbContext;
}

public async Task<FlightDto> Handle(DeleteFlight request, CancellationToken cancellationToken)
public async Task<DeleteFlightResult> Handle(DeleteFlight request, CancellationToken cancellationToken)
{
Guard.Against.Null(request, nameof(request));

Expand All @@ -44,12 +44,12 @@ public async Task<FlightDto> Handle(DeleteFlight request, CancellationToken canc
throw new FlightNotFountException();
}

var deleteFlight = _flightDbContext.Flights.Remove(flight).Entity;
flight.Delete(flight.Id, flight.FlightNumber, flight.AircraftId, flight.DepartureAirportId,
flight.DepartureDate, flight.ArriveDate, flight.ArriveAirportId, flight.DurationMinutes,
flight.FlightDate, flight.Status, flight.Price);

flight.Delete(deleteFlight.Id, deleteFlight.FlightNumber, deleteFlight.AircraftId, deleteFlight.DepartureAirportId,
deleteFlight.DepartureDate, deleteFlight.ArriveDate, deleteFlight.ArriveAirportId, deleteFlight.DurationMinutes,
deleteFlight.FlightDate, deleteFlight.Status, deleteFlight.Price);
var deleteFlight = (_flightDbContext.Flights.Remove(flight))?.Entity;

return _mapper.Map<FlightDto>(deleteFlight);
return new DeleteFlightResult(deleteFlight.Id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ public IEndpointRouteBuilder MapEndpoint(IEndpointRouteBuilder builder)
.WithMetadata(
new SwaggerResponseAttribute(
StatusCodes.Status204NoContent,
"Flight Deleted",
typeof(FlightDto)))
"Flight Deleted"))
.WithMetadata(
new SwaggerResponseAttribute(
StatusCodes.Status400BadRequest,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using BuildingBlocks.IdsGenerator;
using Flight.Flights.Dtos;
using Mapster;

namespace Flight.Flights.Features;

using CreatingFlight.V1;
using DeletingFlight.V1;
using GettingAvailableFlights.V1;
using Models;
using UpdatingFlight.V1;
using FlightDto = Dtos.FlightDto;

public class FlightMappings : IRegister
{
Expand Down
Loading

0 comments on commit 1e6f5b8

Please sign in to comment.