Flexbase
  • Flexbase
  • Introduction
  • #JoyofCoding with Flexbase
  • Core Concepts
    • Flexbase
    • Flexstudio
      • Commands & Events
  • Thinking in Flexbase
    • Features and Modules
    • Designing APIs using Flexbase Control Flow
  • Sample Application
  • Solution Structure
    • Getting Started
      • Application
        • Introduction to Solution
        • Demo - Solution Generation
        • Solution Structure Overview
        • Architecture Overview
        • Clean architecture layer
        • Common Configurations
      • Features
        • Understanding Feature
        • Use Case
        • First Feature - Add Customer
        • Second Feature - Update Customer
        • Third Feature - Delete Customer
        • Query Features
  • Input Output Models
  • Messages
  • Domain
  • Pre Bus
  • Post Bus
  • Subscribers
  • Bus Gamma
  • Persistence
  • Hosting
  • Startup Code - WebAPI
  • Startup Code - Background Job
  • Endpoint - AppSettings
  • Bridge
  • Basic CRUD - Insert & Update
  • Introduction
  • View Generated API Definition in Swagger
  • Walkthrough Generated Code Insert
  • Walkthrough Generated Code Query GetById
  • Domain Model
  • Migration
  • AppSettings
  • Bus : How Basic Routing Config Works
  • INSERT : Input API Model
  • INSERT : Attribute Validation
  • INSERT : Plugin Validation
  • INSERT : Mapper
  • INSERT : Controller
  • INSERT : Services
  • INSERT : PostBus Handler
  • INSERT : PostBus Subscriber
  • INSERT : Demo In Action
  • QUERY : Output API Model
  • QUERY : Build and Fetch Pattern
  • QUERY : Demo In Action
  • Basic CRUD 2
    • Introduction
    • View Generated API Definition In Swagger
  • Walkthrough Generated Code Update
  • Walkthrough Generated Code Delete
  • Walkthrough Generated Code GetList
  • Walkthrough Generated Code Get Paged List
  • Update In Action
  • Delete In Action
  • GetList In Action
  • GetPagedList In Action
  • Konarch
Powered by GitBook
On this page

Walkthrough Generated Code Update

BasicCRUD Part 2

PreviousView Generated API Definition In SwaggerNextWalkthrough Generated Code Delete

Last updated 4 years ago

Now let us walk through the generated code for the update and come back to our solution.

The first thing is the input API model. Keeping a separate input api model is very handy in maintaining the fields for update and keeping the unwanted fields out of the flow.

public class UpdateCustomerInputAPIModel : IFlexInputAPIModel
    {
        [StringLength(32)]
        public string Id { get; set; }

        [StringLength(50)]
        public string Name { get; set; }
    }

Let’s now see the update customer.

public partial class CustomerController : FlexControllerBridge
    {

        [HttpPut]
        [Route("UpdateCustomer")]
        [ProducesResponseType(typeof(BadRequestResult), 400)]
        [ProducesResponseType(typeof(string), 200)]
        public async Task<IActionResult> UpdateCustomer([FromBody]UpdateCustomerInputAPIModel value)
        {
            if (value == null)
            {
                ModelState.AddModelError("requesterror", $"{nameof(UpdateCustomerInputAPIModel)} can not be empty");
                _logger.LogDebug($"{nameof(UpdateCustomerInputAPIModel)} can not be empty" + DateTime.Now.ToString());
                return ControllerContext.ReturnFlexBadRequestError();
            }

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            CommandResult cmdResult = null;

            UpdateCustomerParams updateParams = new UpdateCustomerParams();

            FlexHostContextInfoBridge hostContextInfo = new FlexHostContextInfoBridge();
            hostContextInfo.Populate<IFlexHostHttpContextAccesorBridge>(_appHttpContextAccessor);
            updateParams.HostContextInfo = hostContextInfo;

            updateParams.Model = value;
 
            cmdResult = await ProcessCustomerService.UpdateCustomer(updateParams);

            if (cmdResult.Status != Status.Success)
            {
                ModelState.ComposeFlexBadRequestError(cmdResult.Errors());
                return ControllerContext.ReturnFlexBadRequestError();
            }
            return Ok(cmdResult.result);
        }
    }

The input is received in the action. We have the HTTP PUT automatically configured for the update customer. Action functions as it was explained in the POST in earlier section.

Lets look at the Services layer.

Here all the plugins are executed for the validations.

public partial class ProcessCustomerService : IProcessCustomerService
    {
        
        /// <summary>
        /// YourRemarksForMethod
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<CommandResult> UpdateCustomer(UpdateCustomerParams param)
        {
            UpdateCustomerDataPacket packet = _flexHost.GetFlexiFlowDataPacket<UpdateCustomerDataPacket>();
            packet.InputParams = param;

            try
            {
                FlexiBusinessRuleSequenceBase<UpdateCustomerDataPacket> sequence = _flexHost.GetFlexiBusinessRuleSequence<UpdateCustomerSequence, UpdateCustomerDataPacket>();

                await FlexiBusinessRule.Run(sequence, packet);
            }
            catch (FlexiFlowAbnormalTerminationException ex)
            {
                packet.AddError("requesterror", ex);
                return new CommandResult(Status.Failed, packet.Errors());
            }

            if (packet.HasError)
            {
                return new CommandResult(Status.Failed, packet.Errors());
            }
            else
            {
                UpdateCustomerCommand cmd = new UpdateCustomerCommand
                {
                    model = param.Model,
                    HostContextInfo = param.HostContextInfo

                };

                await ProcessCommand(cmd);

                CommandResult cmdResult = new CommandResult(Status.Success);
                UpdateCustomerResultModel outputResult = new UpdateCustomerResultModel();
                cmdResult.result = outputResult;
                return cmdResult;
            }
        }
    }
    public class UpdateCustomerResultModel : FlexOutputAPIModelForUpdate
    {
    }
public partial class ProcessCustomerService : IProcessCustomerService
    {
        private async Task ProcessCommand(UpdateCustomerCommand cmd)
        {
            await _bus.Send(cmd);

        }
    }

Here if it is non eventual the command is sent to the bus. The bus receives the command update customer Handler and executes the plugin for the Post bus so we go to the plug-in.

Update customer plugin. So here the flow is the same as your insert. All validations follow the same process. So this is the method in the domain model and the rest of the things Remains the Same insert or update model.

Let us look at the update customer model.

public partial class Customer : DomainModelBridge
    {

        public virtual Customer UpdateCustomer(UpdateCustomerCommand cmd)
        {
            Guard.AgainstNull("Customer model cannot be empty", cmd);
            this.Convert(cmd.model);
            this.LastModifiedBy = cmd.HostContextInfo.UserId;

            //Map any other field not handled by Automapper config

            this.SetModified();

            //Set your appropriate SetModified for the inner object here

            return this;
        }

    }

Now we'll go to the mapper and see what we have done, there is no domain in the mapper.

        public CustomerMapperConfiguration() : base()
        {
            #region Input

            CreateMap<UpdateCustomerInputAPIModel, Customer>();

            #endregion
        }

Once the update happens. The same way the event is raised here. On success and then it is further processed by subscribers or handlers.