<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mannawar Hussain</title>
    <description>The latest articles on DEV Community by Mannawar Hussain (@mannawar).</description>
    <link>https://dev.to/mannawar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F300469%2F2c3c1bca-f36a-4107-9ac4-584b288cc395.jpeg</url>
      <title>DEV Community: Mannawar Hussain</title>
      <link>https://dev.to/mannawar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mannawar"/>
    <language>en</language>
    <item>
      <title>FHIR crud app using aspnet core 8.0 and sql server</title>
      <dc:creator>Mannawar Hussain</dc:creator>
      <pubDate>Sat, 13 Jul 2024 11:35:58 +0000</pubDate>
      <link>https://dev.to/mannawar/fhir-crud-app-using-aspnet-core-80-and-sql-server-59p1</link>
      <guid>https://dev.to/mannawar/fhir-crud-app-using-aspnet-core-80-and-sql-server-59p1</guid>
      <description>&lt;p&gt;Hi EveryOne!&lt;br&gt;
I would like to discuss today, the crud operation for the patient resource using HL7 R4 model using aspnet core and saving of patient data on sql server using EF Core. For modelling of data i have used this package.&lt;br&gt;
Ref- &lt;a href="https://www.nuget.org/packages/Hl7.Fhir.R4" rel="noopener noreferrer"&gt;https://www.nuget.org/packages/Hl7.Fhir.R4&lt;/a&gt;, &lt;a href="https://www.hl7.org/fhir/resource.html#identification" rel="noopener noreferrer"&gt;https://www.hl7.org/fhir/resource.html#identification&lt;/a&gt;&lt;br&gt;
Here each resource is uniquely identified by the id. I have given Id as database generated, we dont need to specifically specify that while sending request. So basically, this is my PatientEntity class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   public class PatientEntity
  {
      [Key]
      [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
      public string Id { get; set; } = Guid.NewGuid().ToString();


      [Required]
      public string FamilyName { get; set; } = string.Empty;

      [Required]
      public string GivenName { get; set; } = string.Empty;

      [Required]
      public string Gender { get; set; } = string.Empty;

      [Required]
      public DateTime BirthDate { get; set; } = DateTime.MinValue;

      public byte[]? PhotoData { get; set; }

      public static PatientEntity FromFhirPatient(Patient patient)
      {
          byte[]? photoData = null;
          if(patient.Photo != null &amp;amp;&amp;amp; patient.Photo.Count &amp;gt; 0 &amp;amp;&amp;amp; patient.Photo[0].Data != null)
          {
              photoData = patient.Photo[0].Data;
          }
          DateTime birthDate = patient.BirthDateElement?.ToDateTimeOffset()?.DateTime ?? DateTime.MinValue;

          return new PatientEntity
          {
              Id = patient.Id ?? Guid.NewGuid().ToString(),
              FamilyName = patient.Name.FirstOrDefault()?.Family ?? string.Empty,
              GivenName = patient.Name.FirstOrDefault()?.Given.FirstOrDefault()?? string.Empty,
              Gender = patient.Gender.HasValue ? patient.Gender.Value.ToString(): string.Empty,
              BirthDate = birthDate,
              PhotoData = photoData
          };
      }

      public Patient ToFhirPatient()
      {
          return new Patient
          {
              Id = Id,
              Name = new List&amp;lt;HumanName&amp;gt;
              {
                  new HumanName
                  {
                      Family = FamilyName,
                      Given = new List&amp;lt;string&amp;gt; { GivenName }
                  }
              },
              Gender = !string.IsNullOrEmpty(Gender) ? (AdministrativeGender)Enum.Parse(typeof(AdministrativeGender), Gender, true) : null,
              BirthDate = BirthDate.ToString("yyyy-MM-dd"),
              Photo = PhotoData != null ? new List&amp;lt;Attachment&amp;gt; { new Attachment { Data = PhotoData } } : null
          };
      }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The properties defined above are as per HL7 R4 model and then i have defined two static methods viz. FromFhirPatient(converts a Patient object from Fhir model to PatientEntity object) and ToFhirPatient(converts a PatientEntity object to a Fhir Patient object).&lt;/p&gt;

&lt;p&gt;The details for modelling classes could be find here. we can customize accordingly. &lt;br&gt;
Flag &lt;code&gt;Σ&lt;/code&gt; means its a modifier element, and it can change interpretation of resource, and is helpful for client to search summary only from large resource of data and helps in improving efficiency, and then there is cardinality ex.(0..1) meaning this particular field can appear minimum 0 times and maximum of 1. More details for data modelling can be find here Ref- &lt;code&gt;https://www.hl7.org/fhir/patient.html&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The blow code is for configuring DbContext.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions&amp;lt;ApplicationDbContext&amp;gt; options) : base(options) { }

        public DbSet&amp;lt;PatientEntity&amp;gt; Patients { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The constructor here &lt;code&gt;public ApplicationDbContext(DbContextOptions&amp;lt;ApplicationDbContext&amp;gt; options) : base(options) { }&lt;/code&gt; Here ApplicationDbContext is properly configured by Dependency injection system which helps in SOC and it helps in configuring options for DbContext which typically includes things like database connection etc inside Program.cs which i will discuss next.&lt;br&gt;
&lt;code&gt;base(options)&lt;/code&gt; passes the options parameters to the base DbContext constructor.&lt;/p&gt;

&lt;p&gt;This property &lt;code&gt;public DbSet&amp;lt;PatientEntity&amp;gt; Patients { get; set; }&lt;/code&gt; creates a table inside database &lt;br&gt;
ModelBuilder class provides API surface for configuring a DbContext to map entities to db schema.&lt;/p&gt;

&lt;p&gt;This is my Program class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Hl7.Fhir.Model;
using Hl7.Fhir.Serialization;
using Microsoft.EntityFrameworkCore;
using NetCrudApp.Data;
using System.Text.Json.Serialization;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .AddJsonOptions(opt =&amp;gt;
    {
        IList&amp;lt;JsonConverter&amp;gt; fhirConverters = opt.JsonSerializerOptions.ForFhir(ModelInfo.ModelInspector).Converters;
        IList&amp;lt;JsonConverter&amp;gt; convertersToAdd = new List&amp;lt;JsonConverter&amp;gt;(fhirConverters);
        foreach(JsonConverter fhirConverter in convertersToAdd)
        {
            opt.JsonSerializerOptions.Converters.Add(fhirConverter);
        }
        opt.JsonSerializerOptions.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
    });

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext&amp;lt;ApplicationDbContext&amp;gt;(options =&amp;gt;
{
    options.UseSqlServer(connectionString);
});

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddHttpClient(); // added this line to converse with fhir server microsoft



var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();
using (var scope = app.Services.CreateScope())
{
    var dbContext = scope.ServiceProvider.GetRequiredService&amp;lt;ApplicationDbContext&amp;gt;();
    await dbContext.Database.MigrateAsync();
}

app.Run();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, in this line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        IList&amp;lt;JsonConverter&amp;gt; fhirConverters = opt.JsonSerializerOptions.ForFhir(ModelInfo.ModelInspector).Converters;
        IList&amp;lt;JsonConverter&amp;gt; convertersToAdd = new List&amp;lt;JsonConverter&amp;gt;(fhirConverters);
        foreach(JsonConverter fhirConverter in convertersToAdd)
        {
            opt.JsonSerializerOptions.Converters.Add(fhirConverter);
        }
        opt.JsonSerializerOptions.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is required for Serialization of data, otherwise this will throw error &lt;code&gt;The collection type 'Hl7.Fhir.Model.Patient' is abstract, an interface, or is read only, and could not be instantiated and populated.&lt;/code&gt; &lt;br&gt;
Also, we need to initialize a new converter as &lt;code&gt;IList&amp;lt;JsonConverter&amp;gt; convertersToAdd = new List&amp;lt;JsonConverter&amp;gt;(fhirConverters);&lt;/code&gt; else we will end up in modifying the original list which is not of course we want. Also, this line &lt;code&gt;opt.JsonSerializerOptions.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;&lt;/code&gt; allows characters that are particularly escaped like &amp;amp;, &amp;lt;, &amp;gt; to remain unescaped, which is useful for interoperability and readability of json output but it should be cautiously used. In summary this converter is used for serialization and deserialization of fhir model data which is of complex type and is challenging to perform &lt;strong&gt;deserialization&lt;/strong&gt; for saving data on database and ** serializing** while returning response to client using native converters like NewtonSoft. Ref here - &lt;code&gt;https://github.com/FirelyTeam/firely-net-sdk/issues/2583&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext&amp;lt;ApplicationDbContext&amp;gt;(options =&amp;gt;
{
    options.UseSqlServer(connectionString);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;specifies the connection string for the app which is defined inside appSetting.json. For simplicity sake i have just defined the variables inside my appsettings.json as below as we are developing is using local sql server only. For azure deployment, we can configure services to manage secrets properly. appsettings.json is as below, it simply specifies the connection string and logging level, if we want more info from logging just change from &lt;code&gt;warning&lt;/code&gt; to &lt;code&gt;Information&lt;/code&gt; inside appsettings.json or appsettings.Development.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Server=.;Database=FhirLocalDb;Integrated Security=true;TrustServerCertificate=true;"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Further, this line inside Program.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using (var scope = app.Services.CreateScope())
{
    var dbContext = scope.ServiceProvider.GetRequiredService&amp;lt;ApplicationDbContext&amp;gt;();
    await dbContext.Database.MigrateAsync();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is used to apply any pending migration. But before that we need to add migration and update database using below commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet ef migrations add InitialCreate
dotnet ef database update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, this is my PatientController class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Route("fhir/patient")]
[ApiController]
public class PatientResourceProvider : ControllerBase
{
    private readonly ApplicationDbContext _context;

    public PatientResourceProvider(ApplicationDbContext context)
    {
        _context = context;
    }

    [HttpGet("{id}")]
    public async Task&amp;lt;IActionResult&amp;gt; GetPatient(string id)
    {
        try
        {
            //https://stackoverflow.com/questions/62899915/converting-null-literal-or-possible-null-value-to-non-nullable-type
            PatientEntity? patientEntity = await _context.Patients.FindAsync(id);
            if(patientEntity != null)
            {
                return Ok(patientEntity);
            }else
            {
                return NotFound(new { Message = "Patient not found" });
            }

        }catch(FhirOperationException ex) when (ex.Status == System.Net.HttpStatusCode.NotFound)
        {
            return NotFound(new { Message = "Patient not found" });
        }catch(Exception ex)
        {
            return StatusCode(500, new { Message = "Ann error occurred", Details = ex.Message });
        }
    }

    [HttpPost]
    public async Task&amp;lt;IActionResult&amp;gt; CreatePatient([FromBody] Patient patient)
    {
        using var transaction = await _context.Database.BeginTransactionAsync();
        try
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            PatientEntity patientEntity = PatientEntity.FromFhirPatient(patient);
            _context.Patients.Add(patientEntity);
            await _context.SaveChangesAsync();

            await transaction.CommitAsync();

            return CreatedAtAction(nameof(GetPatient), new { id = patientEntity.Id }, patientEntity.ToFhirPatient());
        }
        catch (Exception ex)
        {
            await transaction.RollbackAsync();  
            return StatusCode(500, new { Message = "An error occurred", Details = ex.Message });
        }
    }

    [HttpPut("{id}")]
    public async Task&amp;lt;IActionResult&amp;gt; UpdatePatient(string id, [FromBody] Patient patient)
    {
        if(id == null)
        {
            return BadRequest(new {Message = "Patient id cannot be null"});
        }

        using var transaction = await _context.Database.BeginTransactionAsync();

        try
        {
            PatientEntity? patientEntity = await _context.Patients.FindAsync(id);
            if(patientEntity == null)
            {
                return NotFound(new { Message = "Patient not found" });
            }

            if(patient.Name == null || patient.Name.Count == 0 || string.IsNullOrEmpty(patient.Name[0].Family)) {
                return BadRequest(new { Message = "Patient name is required" });
            }

            patientEntity.FamilyName = patient.Name.FirstOrDefault()?.Family ?? string.Empty; 
            patientEntity.GivenName = patient.Name.FirstOrDefault()?.Given.FirstOrDefault() ?? string.Empty;
            patientEntity.Gender = patient.Gender.HasValue ? patient.Gender.Value.ToString().ToLower() : string.Empty;
            patientEntity.BirthDate = patient.BirthDateElement?.ToDateTimeOffset()?.DateTime ?? DateTime.MinValue;

            _context.Entry(patientEntity).State = EntityState.Modified;

            await _context.SaveChangesAsync();

            await transaction.CommitAsync();

            return NoContent();
        }catch(DbUpdateConcurrencyException) 
        {
            if(!_context.Patients.Any(e =&amp;gt; e.Id == id))
            {
                return NotFound(new { Message = "Patient not found" });
            }
            else
            {
                throw;
            }
        }catch(Exception ex)
        {
            await transaction.RollbackAsync();
            return StatusCode(500, new { Message = "An error occurred", Details = ex.Message });
        }
    }


    [HttpDelete("{id}")]
    public async Task&amp;lt;IActionResult&amp;gt; DeletePatient(string id)
    {
        using var transaction = await _context.Database.BeginTransactionAsync();
        try
        {
            var patientEntity = await _context.Patients.FindAsync(id);
            if(patientEntity == null)
            {
                return NotFound(new { Message = "Patient not found" });
            }
            _context.Patients.Remove(patientEntity);
            await _context.SaveChangesAsync();
            await transaction.CommitAsync();
            return NoContent();
        }catch(Exception ex)
        {
            await transaction.RollbackAsync();
            return StatusCode(500, new { Message = "An error occurred", Details = ex.Message });
        }
    }

    [HttpGet("search")]
    public async Task&amp;lt;IActionResult&amp;gt; SearchPatient([FromQuery] string? name = null, string? id = null)
    {
        try
        {
            IQueryable&amp;lt;PatientEntity&amp;gt; query = _context.Patients;
            if (!string.IsNullOrEmpty(name))
            {
                query = query.Where(n =&amp;gt;  n.FamilyName == name || n.GivenName == name);
            }
            if (!string.IsNullOrEmpty(id))
            {
                query = query.Where(p =&amp;gt; p.Id == id);
            }

            var patients = await query.ToListAsync();
            if (!patients.Any())
            {
                return NotFound(new { Message = "No Patient found" });
            }
            return Ok(patients);
        }catch(Exception ex)
        {
            return StatusCode(500, new { Message = "An error occurred", Details = ex.Message });
        }
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Starting from Post request as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; [HttpPost]
 public async Task&amp;lt;IActionResult&amp;gt; CreatePatient([FromBody] Patient patient)
 {
     using var transaction = await _context.Database.BeginTransactionAsync();
     try
     {
         if (!ModelState.IsValid)
         {
             return BadRequest(ModelState);
         }
         PatientEntity patientEntity = PatientEntity.FromFhirPatient(patient);
         _context.Patients.Add(patientEntity);
         await _context.SaveChangesAsync();
         await transaction.CommitAsync();

         return CreatedAtAction(nameof(GetPatient), new { id = patientEntity.Id }, patientEntity.ToFhirPatient());
     }
     catch (Exception ex)
     {
         await transaction.RollbackAsync();  
         return StatusCode(500, new { Message = "An error occurred", Details = ex.Message });
     }
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We start writing defensively to catch any errors, first database transaction is started asynchronously to maintain integrity of data saved on sql server. If any parts fails here it will Rollback the transaction. Then here &lt;code&gt;if (!ModelState.IsValid)&lt;br&gt;
         {&lt;br&gt;
             return BadRequest(ModelState);&lt;br&gt;
         }&lt;/code&gt; model state is verified as per the attributes and rules defined inside Patient model class, if there is model validation error it will throw 400.&lt;/p&gt;

&lt;p&gt;Then this line of code &lt;code&gt;PatientEntity patientEntity = PatientEntity.FromFhirPatient(patient);&lt;/code&gt; will &lt;strong&gt;deserialize&lt;/strong&gt; data from entity class in order to save data on database.&lt;/p&gt;

&lt;p&gt;These three lines &lt;code&gt;_context.Patients.Add(patientEntity);&lt;br&gt;
         await _context.SaveChangesAsync();&lt;br&gt;
         await transaction.CommitAsync();&lt;/code&gt; will add new patient based upon request from body and save in db and commit transaction. &lt;br&gt;
If any error is thrown transactionwill be rolled back here &lt;code&gt;await transaction.RollbackAsync();&lt;/code&gt; and in case of any error it will be catched inside catch block. The successful post request in postman would look something like this. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8p956z1jtb4tbzuezz3o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8p956z1jtb4tbzuezz3o.png" alt="Image description" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similarly, for get request here&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; [HttpGet("{id}")]
 public async Task&amp;lt;IActionResult&amp;gt; GetPatient(string id)
 {
     try
     {
         PatientEntity? patientEntity = await _context.Patients.FindAsync(id);
         if(patientEntity != null)
         {
             return Ok(patientEntity);
         }else
         {
             return NotFound(new { Message = "Patient not found" });
         }

     }catch(FhirOperationException ex) when (ex.Status == System.Net.HttpStatusCode.NotFound)
     {
         return NotFound(new { Message = "Patient not found" });
     }catch(Exception ex)
     {
         return StatusCode(500, new { Message = "Ann error occurred", Details = ex.Message });
     }
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We first try to find a given entity using primary id here &lt;code&gt;PatientEntity? patientEntity = await _context.Patients.FindAsync(id);&lt;/code&gt; Here &lt;strong&gt;PatientEntity?&lt;/strong&gt; question mark is used in order to ward off &lt;code&gt;warning CS8600  Converting null literal or possible null value to non-nullable type.&lt;/code&gt;&lt;br&gt;&lt;br&gt;
If patientEntity is not null, then a matching patientEntity is returned from db here  using response as &lt;code&gt;return Ok(patientEntity);&lt;/code&gt; else the errors are catched inside catch blocks. &lt;strong&gt;FhirOperationException&lt;/strong&gt; is derived from base Exception class and it represents HL7 FHIR errors that occur during application execution.&lt;br&gt;
Successful, Postman request for get request is as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft6ye19p11bigne43j5v4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft6ye19p11bigne43j5v4.png" alt="Image description" width="800" height="414"&gt;&lt;/a&gt;&lt;br&gt;
Likewise, for put operation here&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; [HttpPut("{id}")]
 public async Task&amp;lt;IActionResult&amp;gt; UpdatePatient(string id, [FromBody] Patient patient)
 {
     if(id == null)
     {
         return BadRequest(new {Message = "Patient id cannot be null"});
     }

     using var transaction = await _context.Database.BeginTransactionAsync();

     try
     {
         PatientEntity? patientEntity = await _context.Patients.FindAsync(id);
         if(patientEntity == null)
         {
             return NotFound(new { Message = "Patient not found" });
         }

         if(patient.Name == null || patient.Name.Count == 0 || string.IsNullOrEmpty(patient.Name[0].Family)) {
             return BadRequest(new { Message = "Patient name is required" });
         }

         patientEntity.FamilyName = patient.Name.FirstOrDefault()?.Family ?? string.Empty; 
         patientEntity.GivenName = patient.Name.FirstOrDefault()?.Given.FirstOrDefault() ?? string.Empty;
         patientEntity.Gender = patient.Gender.HasValue ? patient.Gender.Value.ToString().ToLower() : string.Empty;
         patientEntity.BirthDate = patient.BirthDateElement?.ToDateTimeOffset()?.DateTime ?? DateTime.MinValue;

         _context.Entry(patientEntity).State = EntityState.Modified;

         await _context.SaveChangesAsync();

         await transaction.CommitAsync();

         return NoContent();
     }catch(DbUpdateConcurrencyException) 
     {
         if(!_context.Patients.Any(e =&amp;gt; e.Id == id))
         {
             return NotFound(new { Message = "Patient not found" });
         }
         else
         {
             throw;
         }
     }catch(Exception ex)
     {
         await transaction.RollbackAsync();
         return StatusCode(500, new { Message = "An error occurred", Details = ex.Message });
     }
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, null check of id is done which is found inside query parameter of request url and then to update the given property is locked using this block as in post request to maintain data integrity inside db here &lt;code&gt;using var transaction = await _context.Database.BeginTransactionAsync();&lt;/code&gt;&lt;br&gt;
Here in this line &lt;code&gt;if(patientEntity == null)&lt;br&gt;
    {&lt;br&gt;
        return NotFound(new { Message = "Patient not found" });&lt;br&gt;
    }&lt;/code&gt; if patient with given id is not found, then 404 not found is returned as response with its according message.&lt;br&gt;
Here &lt;code&gt;if(patient.Name == null || patient.Name.Count == 0 || string.IsNullOrEmpty(patient.Name[0].Family)) {&lt;br&gt;
                    return BadRequest(new { Message = "Patient name is required" });&lt;br&gt;
                }&lt;/code&gt; it validates the Patient incoming object. And it checks if Name property of patient object is null or if Name count is zero or if the family Name of the first HumanName is empty or null will throw 400 validation error as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F93m9xzy3fgg5s5p0ylaq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F93m9xzy3fgg5s5p0ylaq.png" alt="Image description" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, in these four lines FamilyName, GivenName, Gender and BirthDate are mapped to either the values provided by the client or else will be mapped to empty string. Only, BirthDate is first converted to DateTimeOffset and then to DateTime and if conversion fails or is null then it assigns DateTime.MinValue;&lt;/p&gt;

&lt;p&gt;This line &lt;code&gt;_context.Entry(patientEntity).State = EntityState.Modified;&lt;/code&gt; marks the patient entity to be modified and tells EF core that &lt;strong&gt;patientEntity&lt;/strong&gt; has been modified and needs to be updated in database.&lt;/p&gt;

&lt;p&gt;And another two lines here `                await _context.SaveChangesAsync();&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            await transaction.CommitAsync();` save changes in database and commit transaction and returns 204 no content. Else the error is catched inside catch block.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Successful postman request is &lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzuvxqigvbwirc5z6ywsa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzuvxqigvbwirc5z6ywsa.png" alt="Image description" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note- We use Patient model as method parameter here since we have to adhere to HL7 Fhir model.&lt;/p&gt;

&lt;p&gt;Further, delete method is also locked inside database transaction as well in order to maintain data integrity&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        [HttpDelete("{id}")]
        public async Task&amp;lt;IActionResult&amp;gt; DeletePatient(string id)
        {
            using var transaction = await _context.Database.BeginTransactionAsync();
            try
            {
                var patientEntity = await _context.Patients.FindAsync(id);
                if(patientEntity == null)
                {
                    return NotFound(new { Message = "Patient not found" });
                }
                _context.Patients.Remove(patientEntity);
                await _context.SaveChangesAsync();
                await transaction.CommitAsync();
                return NoContent();
            }catch(Exception ex)
            {
                await transaction.RollbackAsync();
                return StatusCode(500, new { Message = "An error occurred", Details = ex.Message });
            }
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
 First patient is searched using id and then if patient with given id is found then this line &lt;code&gt;_context.Patients.Remove(patientEntity);&lt;/code&gt; will successfully remove patientEntity from db only when this line &lt;code&gt;await _context.SaveChangesAsync();&lt;/code&gt; is executed and transaction is complete and if there is any error, the transaction will be rolled back and error message is displayed accordingly.&lt;br&gt;
Successful postman request for this operation is as here. &lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp5h0ig95lyy0khie2u3c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp5h0ig95lyy0khie2u3c.png" alt="Image description" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the Search operation is by id or by name as here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; [HttpGet("search")]
 public async Task&amp;lt;IActionResult&amp;gt; SearchPatient([FromQuery] string? name = null, string? id = null)
 {
     try
     {
         IQueryable&amp;lt;PatientEntity&amp;gt; query = _context.Patients;
         if (!string.IsNullOrEmpty(name))
         {
             query = query.Where(n =&amp;gt;  n.FamilyName == name || n.GivenName == name);
         }
         if (!string.IsNullOrEmpty(id))
         {
             query = query.Where(p =&amp;gt; p.Id == id);
         }

         List&amp;lt;PatientEntity&amp;gt; patients = await query.ToListAsync();
         if (!patients.Any())
         {
             return NotFound(new { Message = "No Patient found" });
         }
         return Ok(patients);
     }catch(Exception ex)
     {
         return StatusCode(500, new { Message = "An error occurred", Details = ex.Message });
     }
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since, we are directly interacting with database here that's why i have used &lt;code&gt;IQueryable&amp;lt;PatientEntity&amp;gt; query = _context.Patients;&lt;/code&gt; &lt;strong&gt;PatientEntity&lt;/strong&gt; type instead of Patient type. Then null and empty string check operation is performed for both id and name and the results are filtered using Where extension method. This line &lt;code&gt;List&amp;lt;PatientEntity&amp;gt; patients = await query.ToListAsync();&lt;/code&gt; results a list of patients matching the records from db and if any error it will be catched inside catch block. Successful postman request is as below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search by name&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnh5bj15yea4rwtnbmt74.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnh5bj15yea4rwtnbmt74.png" alt="Image description" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Search by id &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fclaaap7ler9cxvmfmznr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fclaaap7ler9cxvmfmznr.png" alt="Image description" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can close use/play with below github. No permission is required. In case of any issue feel free to message me i will try to respond asap!&lt;/p&gt;

&lt;p&gt;Repo- &lt;a href="https://github.com/mannawar/fhir-msft-sqlserver" rel="noopener noreferrer"&gt;https://github.com/mannawar/fhir-msft-sqlserver&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for your time!&lt;/p&gt;

</description>
      <category>microsoft</category>
      <category>hl7</category>
      <category>sqlserver</category>
      <category>apnetcore</category>
    </item>
    <item>
      <title>Refactoring..(Part 3)</title>
      <dc:creator>Mannawar Hussain</dc:creator>
      <pubDate>Fri, 28 Jun 2024 14:44:13 +0000</pubDate>
      <link>https://dev.to/mannawar/refactoringpart-3-i5d</link>
      <guid>https://dev.to/mannawar/refactoringpart-3-i5d</guid>
      <description>&lt;p&gt;Hi Everyone!, &lt;br&gt;
Today i would like to discuss further analysis of my code in terms of time and space complexity. This is the backend code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;       [AllowAnonymous]
       [HttpPost("registergoogle")]
       public async Task&amp;lt;ActionResult&amp;lt;UserDto&amp;gt;&amp;gt; RegisterGoogle(GoogleRegisterDto googleRegisterDto)
       {

           GoogleJsonWebSignature.Payload payload;
           try
           {
               payload = await GoogleJsonWebSignature.ValidateAsync(googleRegisterDto.GoogleTokenId);
           }
           catch (Exception ex)
           {
               return Unauthorized(new { Error = "Invalid google token" });
           }
           var email = payload.Email;
           var displayName = payload.Name;
           var userName = payload.Subject;


           var existingUser = await _userManager.Users.FirstOrDefaultAsync(x =&amp;gt; x.UserName == userName || x.Email == email || x.Us_DisplayName == displayName);


           if (existingUser != null)
           {
               if (existingUser.Email == email)
               {
                   return CreateUserObject(existingUser);
               }else
               {
                   ModelState.AddModelError("username", "Username taken");
                   return ValidationProblem();
               }
           }

           var user = new AppUser
           {
               Us_DisplayName = displayName,
               Email = email,
               UserName = userName,
               Us_Active = true,
               Us_Customer = true,
               Us_SubscriptionDays = 0
           };  

           var result = await _userManager.CreateAsync(user);

           if (result.Succeeded)
           {
               return CreateUserObject(user);
           }

           return BadRequest(result.Errors);

       }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I will discuss each portion of the code with regards to its time and space complexity.&lt;/p&gt;

&lt;p&gt;Here &lt;code&gt;payload = await GoogleJsonWebSignature.ValidateAsync(googleRegisterDto.GoogleTokenId);&lt;/code&gt; in this line of code O(n) can be considered as O(1) considering network communication and cryptographic validation, or may be little higher or lower depending upon network communication. But, space complexity will be O(1) as assignment variable(payload).&lt;/p&gt;

&lt;p&gt;Coming down, &lt;code&gt;var email = payload.Email;&lt;br&gt;
var displayName = payload.Name;&lt;br&gt;
var userName = payload.Subject;&lt;/code&gt; These lines are also assignment variable hence both time and space complexity is O(1).&lt;/p&gt;

&lt;p&gt;Now coming to line &lt;code&gt;var existingUser = await _userManager.Users.FirstOrDefaultAsync(x =&amp;gt; x.UserName == userName || x.Email == email || x.Us_DisplayName == displayName);&lt;/code&gt; Time complexity could be O(n) depending upon indexing and size of the AspnetUsers, where n is the no of users inside AspnetUsers table. So, we can simply measure the performance of this piece of code using stopwatch from System.Diagnostics. Hence my code look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();


            var existingUser = await _userManager.Users.FirstOrDefaultAsync(x =&amp;gt; x.UserName == userName || x.Email == email || x.Us_DisplayName == displayName);

            stopwatch.Stop();
            Console.WriteLine($"Exceution time after user query returned from db: {stopwatch.ElapsedMilliseconds}");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;on first call it gives me the time as below.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fje6kfhtbsrwwom0zejjg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fje6kfhtbsrwwom0zejjg.png" alt="Image description" width="662" height="37"&gt;&lt;/a&gt;&lt;br&gt;
It gives me a total time of 1165ms.&lt;/p&gt;

&lt;p&gt;To improve the performance, since this query is related to db and is querying three parameters viz. Username, Email and Us_DisplayName on AspnetUsers. Hence, i have good option to create an index(non-clustered). I created an index on these parameters and measured the performance again. The result is below. &lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqjz7n2uji2qt53978wec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqjz7n2uji2qt53978wec.png" alt="Image description" width="671" height="22"&gt;&lt;/a&gt;&lt;br&gt;
Time has reduced from 1165ms to 742ms.&lt;br&gt;
Hence, we can say that time complexity has reduced from O(n) to O(log(n)) for indexed look up. while space complexity is O(1) as it stores reference to single user object only.&lt;/p&gt;

&lt;p&gt;For the below piece of code time and space complexity would be O(1) as it involves condition check and method call only.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            if (existingUser != null)
            {
                if (existingUser.Email == email)
                {
                    return CreateUserObject(existingUser);
                }else
                {
                    ModelState.AddModelError("username", "Username taken");
                    return ValidationProblem();
                }
            }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Coming down to this lien `            Stopwatch stopwatch2 = new Stopwatch();&lt;br&gt;
            stopwatch2.Start();&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        var result = await _userManager.CreateAsync(user);
        stopwatch2.Stop();
        Console.WriteLine($"Exceution time after creating user: {stopwatch2.ElapsedMilliseconds}");` 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;I measured the performance again here which gives me around 314ms. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuk372akl03zeb8ctk8ti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuk372akl03zeb8ctk8ti.png" alt="Image description" width="518" height="25"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;As this is database insert operation and practically it gives me 314ms, and hence time and space complexity could be considered again of O(1) considering proper indexing and db storage options.&lt;/p&gt;

&lt;p&gt;Lastly, for this line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            if (result.Succeeded)
            {
                return CreateUserObject(user);
            }

            return BadRequest(result.Errors);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Time and space complexity would be O(1) as this is condition checking and method call only.&lt;br&gt;
&lt;strong&gt;Conclusion&lt;/strong&gt;- step by step debugging through the code we were able to analyze the time and space complexity of the code and we have reduced space complexity from O(n) to O(log(n)) for look up operation using indexing.&lt;/p&gt;

&lt;p&gt;This effort is a part of giving back to the community. I hope this would be helpful to some of us. Thanks for your time!&lt;/p&gt;

&lt;p&gt;Ref used- &lt;a href="https://stackoverflow.com/questions/4694574/database-indexes-and-their-big-o-notation" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/4694574/database-indexes-and-their-big-o-notation&lt;/a&gt;, &lt;a href="https://learn.microsoft.com/en-us/sql/relational-databases/indexes/indexes?view=sql-server-ver16" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/sql/relational-databases/indexes/indexes?view=sql-server-ver16&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aspnet</category>
      <category>sql</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>How Authentication works (Part2)</title>
      <dc:creator>Mannawar Hussain</dc:creator>
      <pubDate>Mon, 24 Jun 2024 06:54:04 +0000</pubDate>
      <link>https://dev.to/mannawar/how-authentication-works-part2-3ibb</link>
      <guid>https://dev.to/mannawar/how-authentication-works-part2-3ibb</guid>
      <description>&lt;p&gt;Continuing from part 1, I have done some refactoring. Instead of decoding the token in the frontend and then sending all the information (such as email, displayName, and userName) over HTTPS, I now prefer to send just the token. In the backend, this token is decoded and mapped to the required parameters. This approach ensures that all security aspects are handled by our backend. HTTPS provides secure transit mechanisms, so I did not consider encrypting the token. Finally, I removed the jwt-decode package from the React app.&lt;br&gt;
If you are following from my previous post, the handleGoogleSuccess method would look something like this now in front end React.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const handleGoogleSuccess = (response: any) =&amp;gt; {
        const tokenId = response.credential;
        dispatch(signInWithGoogle({ tokenId}))
            .unwrap()
            .then(() =&amp;gt; {
                toast.success('Registration successful!');
                navigate('/Book');
            })
            .catch((error: any) =&amp;gt; {
                toast.error('Some error occurred - Please try again later');
                console.error('Google sign in failed:', error);
            });

        console.log('Google sign in successful:', response);
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the controller action method would look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     [AllowAnonymous]
     [HttpPost("registergoogle")]
     public async Task&amp;lt;ActionResult&amp;lt;UserDto&amp;gt;&amp;gt; RegisterGoogle(GoogleRegisterDto googleRegisterDto)
     {

         GoogleJsonWebSignature.Payload payload;
         try
         {
             payload = await GoogleJsonWebSignature.ValidateAsync(googleRegisterDto.GoogleTokenId);
         }
         catch (Exception ex)
         {
             return Unauthorized(new { Error = "Invalid google token" });
         }
         var email = payload.Email;
         var displayName = payload.Name;
         var userName = payload.Subject;

         var existingUser = await _userManager.Users.FirstOrDefaultAsync(x =&amp;gt; x.UserName == userName || x.Email == email || x.Us_DisplayName == displayName);

         if(existingUser != null)
         {
             if(existingUser.Email == email)
             {
                 return CreateUserObject(existingUser);
             }else
             {
                 ModelState.AddModelError("username", "Username taken");
                 return ValidationProblem();
             }
         }

         var user = new AppUser
         {
             Us_DisplayName = displayName,
             Email = email,
             UserName = userName,
             Us_Active = true,
             Us_Customer = true,
             Us_SubscriptionDays = 0
         };  

         var result = await _userManager.CreateAsync(user);

         if (result.Succeeded)
         {
             return CreateUserObject(user);
         }

         return BadRequest(result.Errors);

     }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only the changes from the previous method is this line &lt;code&gt;var email = payload.Email;&lt;br&gt;
            var displayName = payload.Name;&lt;br&gt;
            var userName = payload.Subject;&lt;/code&gt;&lt;br&gt;
Now, i am directly mapping the required params to save in db. This smoothen the process of login instead of checking as in the previous method here &lt;code&gt;if (payload.Email != googleRegisterDto.Email)&lt;br&gt;
            {&lt;br&gt;
                return Unauthorized(new { Error = "Email doesnt match google token" });&lt;br&gt;
            }&lt;/code&gt;&lt;br&gt;
And accordingly my GoogleRegisterDto now is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    public class GoogleRegisterDto
    {
        [Required]
        public string GoogleTokenId { get; set; }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we need to add these lines in our Program.cs in order to avoid cross origin opener policy error and cross response embedder policy error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.Use(async (context, next) =&amp;gt;
{
    context.Response.Headers.Add("Cross-Origin-Opener-Policy", "same-origin");
    context.Response.Headers.Add("Cross-Origin-Embedder-Policy", "require-corp");
    await next();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By incorporating COOP and COEP headers, we can enhance security of our app by preventing potential cross origin attack. These headers help isolate our document context and ensure only trusted resources are embedded, reducing the risk of data leaks and malicious code execution.&lt;br&gt;
More can be read here.&lt;/p&gt;

&lt;p&gt;Ref1- &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy"&gt;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ref2- &lt;a href="https://web.dev/articles/why-coop-coep#:%7E:text=Cross%20Origin%20Opener%20Policy%20(COOP,pop%2Dup%2C%20its%20window"&gt;https://web.dev/articles/why-coop-coep#:~:text=Cross%20Origin%20Opener%20Policy%20(COOP,pop%2Dup%2C%20its%20window&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are many aspects of improving upon security aspect and the action should be proactive. Further improvement on this is implementation of  refresh token and only allowing known ip's. &lt;br&gt;
But, this is basic set up to get an idea of the flow and get us started. Thanks for your time again!&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>aspnet</category>
      <category>sqlserver</category>
    </item>
    <item>
      <title>How authentication works (Part 1)</title>
      <dc:creator>Mannawar Hussain</dc:creator>
      <pubDate>Sun, 23 Jun 2024 06:42:06 +0000</pubDate>
      <link>https://dev.to/mannawar/how-authentication-works-3m41</link>
      <guid>https://dev.to/mannawar/how-authentication-works-3m41</guid>
      <description>&lt;p&gt;Recently, i have been developing FullStack app for a client. I would like to share the key takeaways on that as a part of giving back to the community!&lt;/p&gt;

&lt;p&gt;Tech Stack used- React 18, Redux, Aspnet core 7, Sql-server database.&lt;/p&gt;

&lt;p&gt;I am taking Google login/Register as an example here. But the general flow remain same for Apple Login or mobile otp login or any other login mechanism. I will summarize as well in the last as well. When the user clicks on Button as here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    &amp;lt;Box sx={{ display: 'flex', justifyContent: 'center', mb: 2 }}&amp;gt;
                        &amp;lt;GoogleAuth onSuccess={handleGoogleSuccess} onError={handleGoogleFailure} /&amp;gt;
                    &amp;lt;/Box&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the handleGoogleSuccess method i am using jwtDecode library which breaks the jwt token into three parts and i have mapped it is as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const tokenId = response.credential;
        const decodedToken = jwtDecode&amp;lt;GoogleTokenPayload&amp;gt;(tokenId);

        const email = decodedToken.email;
        const displayName = decodedToken.name;
        const username = decodedToken.sub;

  dispatch(signInWithGoogle({ tokenId, email, displayName, username }))
            .unwrap()
            .then(() =&amp;gt; {
                toast.success('Registration successful!');
                navigate('/Book');
            })
            .catch((error: any) =&amp;gt; {
                toast.error('Some error occurred - Please try again later');
                console.error('Google sign in failed:', error);
            });

        console.log('Google sign in successful:', response);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we know jwt is basically made up of three parts viz. Header, payload and signature. using payload i have mapped above properties to send in backend. More details about jwt can be read in the link below.&lt;br&gt;
&lt;em&gt;Ref- &lt;a href="https://jwt.io/"&gt;https://jwt.io/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Next, I am using Redux for centralizing all account related stuff for user. The exact part of code which is responsible for sending payload to backend is below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const signInWithGoogle = createAsyncThunk&amp;lt;User, GoogleSignInPayLoad&amp;gt;(
    'account/signInWithGoogle',
    async (payload, thunkAPI) =&amp;gt; {
        try {
            const {tokenId, email, displayName, username} = payload;
            const user = await agent.Account.registerGoogle({ GoogleTokenId: tokenId, email, displayName, username });
            localStorage.setItem('user', JSON.stringify(user));
            return user;
        } catch(error: any){
            return thunkAPI.rejectWithValue({ error: error.data });
        }
    }
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the three payload viz. email, displayName, username alongwith tokenId is sent via agent method as here. And if request is successful the localstorage is set with the logged in user credential as shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ferkwbjl8tyxoypfhg0yq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ferkwbjl8tyxoypfhg0yq.png" alt="Image description" width="800" height="93"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;registerGoogle: (values: any) =&amp;gt; requests.post('account/registergoogle', values),
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just to give brief on redux store set up. Root reducer are pure functions which is defined inside ConfigureStore function as below. &lt;code&gt;Reducers are pure function which takes current state and action as an argument and return a new state result.&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const store = configureStore({
    reducer: {
        book: bookSlice.reducer,
        account: accountSlice.reducer,
        subscription: basketSlice.reducer,
        progress: progressSlice.reducer
    },
})

export type RootState = ReturnType&amp;lt;typeof store.getState&amp;gt;;
export type AppDispatch = typeof store.dispatch;

export const useAppDispatch = () =&amp;gt; useDispatch&amp;lt;AppDispatch&amp;gt;();
export const useAppSelector: TypedUseSelectorHook&amp;lt;RootState&amp;gt; = useSelector;  

export default store;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here this line &lt;code&gt;export type RootState = ReturnType&amp;lt;typeof store.getState&amp;gt;;&lt;/code&gt; represents the type of entire redux state in a type safe manner across the application.&lt;/p&gt;

&lt;p&gt;This line &lt;code&gt;export type AppDispatch = typeof store.dispatch;&lt;/code&gt; is just telling typeScript of new type AppDispatch.&lt;code&gt;store.dispatch&lt;/code&gt; is function provided by redux that is used to dispatch action to the store. Hence, AppDispatch will be typed by the exact type of the dispatch function from redux store.&lt;/p&gt;

&lt;p&gt;Further, coming to this line &lt;code&gt;export const useAppDispatch = () =&amp;gt; useDispatch&amp;lt;AppDispatch&amp;gt;();&lt;/code&gt; useAppDispatch is custom React hook which calls internally useDispatch hook with AppDispatch type. As it is exported it can be easily used inside other modules or component by just importing it.&lt;/p&gt;

&lt;p&gt;Lastly, this line &lt;code&gt;export const useAppSelector: TypedUseSelectorHook&amp;lt;RootState&amp;gt; = useSelector;&lt;/code&gt; useSelector is another hook provided by React-Redux. Its function is to extract data from the redux store state in functional components. However, useSelector inherently is not typed to infer the type of redux state automatically. To achieve type safety and avoid repetitive type annotation, TypedUseSelectorHook is provided.&lt;/p&gt;

&lt;p&gt;Then we can further easily use &lt;code&gt;useAppSelector&lt;/code&gt; in any of our component like this as below. &lt;br&gt;
&lt;code&gt;import { useAppSelector } from './store';&lt;/code&gt;&lt;br&gt;
To use this first import inside your component and then &lt;code&gt;const user = useAppSelector(state =&amp;gt; state.user);&lt;/code&gt; Here, we are selecting user slice from redux store and state has a type RootState.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;More or redux can be read here- &lt;a href="https://redux.js.org/tutorials/fundamentals/part-3-state-actions-reducers"&gt;https://redux.js.org/tutorials/fundamentals/part-3-state-actions-reducers&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Next, the request will go to backend via agent.ts method registerGoogle. &lt;/p&gt;

&lt;p&gt;It will hit inside the controller action method as defined here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  [AllowAnonymous]
  [HttpPost("registergoogle")]
  public async Task&amp;lt;ActionResult&amp;lt;UserDto&amp;gt;&amp;gt; RegisterGoogle(GoogleRegisterDto googleRegisterDto)
  {

      GoogleJsonWebSignature.Payload payload;
      try
      {
          payload = await GoogleJsonWebSignature.ValidateAsync(googleRegisterDto.GoogleTokenId);
      }
      catch (Exception ex)
      {
          return Unauthorized(new { Error = "Invalid google token" });
      }
      if (payload.Email != googleRegisterDto.Email)
      {
          return Unauthorized(new { Error = "Email doesnt match google token" });
      }

      var existingUser = await _userManager.Users.FirstOrDefaultAsync(x =&amp;gt; x.UserName == googleRegisterDto.Username || x.Email == googleRegisterDto.Email || x.Us_DisplayName == googleRegisterDto.DisplayName);

      if(existingUser != null)
      {
          if(existingUser.Email == googleRegisterDto.Email)
          {
              return CreateUserObject(existingUser);
          }else
          {
              ModelState.AddModelError("username", "Username taken");
              return ValidationProblem();
          }
      }

      var user = new AppUser
      {
          Us_DisplayName = googleRegisterDto.DisplayName,
          Email = googleRegisterDto.Email,
          UserName = googleRegisterDto.Username,
          Us_Active = true,
          Us_Customer = true,
          Us_SubscriptionDays = 0
      };

      var result = await _userManager.CreateAsync(user);

      if (result.Succeeded)
      {
          return CreateUserObject(user);
      }

      return BadRequest(result.Errors);

  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, since any user can register hence the attribute &lt;code&gt;AllowAnonymous&lt;/code&gt; is used else protect the route by any mechanism or attribute like use &lt;code&gt;Authorize&lt;/code&gt; &lt;br&gt;
In the backend i am using nuget package &lt;code&gt;Google.Apis.Auth&lt;/code&gt; and these lines&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;GoogleJsonWebSignature.Payload payload;&lt;br&gt;
      try&lt;br&gt;
      {&lt;br&gt;
          payload = await GoogleJsonWebSignature.ValidateAsync(googleRegisterDto.GoogleTokenId);&lt;br&gt;
      }&lt;br&gt;
      catch (Exception ex)&lt;br&gt;
      {&lt;br&gt;
          return Unauthorized(new { Error = "Invalid google token" });&lt;br&gt;
      }&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 are responsible for checking &lt;code&gt;googleRegisterDto.GoogleTokenId&lt;/code&gt; is valid and belongs to user attempting to register.&lt;/p&gt;

&lt;p&gt;This line of code checks in database&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;var existingUser = await **_userManager.Users**.FirstOrDefaultAsync(x =&amp;gt; x.UserName == googleRegisterDto.Username || x.Email == googleRegisterDto.Email || x.Us_DisplayName == googleRegisterDto.DisplayName);&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 if database already has the record related to the user attempting to register.&lt;/p&gt;

&lt;p&gt;Further, down this line&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;if(existingUser != null)&lt;br&gt;
{&lt;br&gt;
    if(existingUser.Email == googleRegisterDto.Email)&lt;br&gt;
    {&lt;br&gt;
        return CreateUserObject(existingUser);&lt;br&gt;
    }&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 checks if existing user is not null and and the email from the payload which user sends from frontend matches then CreateUserObject function is called which is as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        private UserDto CreateUserObject(AppUser user)
        {
            return new UserDto
            {
                DisplayName = user.Us_DisplayName,
                Image = user.Md_ID.ToString(),
                Token = _tokenService.CreateToken(user),
                Username = user.UserName,
                FirebaseUID = user.Us_FirebaseUID,
                FirebaseToken = user.Us_FirebaseToken,
                Language = user.Us_language,
                IsSubscribed = (user.Us_SubscriptionExpiryDate != null &amp;amp;&amp;amp; user.Us_SubscriptionExpiryDate &amp;gt; DateTime.Now)
            };
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above, most crucial is this one &lt;code&gt;Token = _tokenService.CreateToken(user)&lt;/code&gt; where the token is created for the user attempting to register whose records have already matched with the user saved in db, for further interaction with app.&lt;/p&gt;

&lt;p&gt;Now, coming further down this line of code &lt;br&gt;
&lt;code&gt;var user = new AppUser&lt;br&gt;
            {&lt;br&gt;
                Us_DisplayName = googleRegisterDto.DisplayName,&lt;br&gt;
                Email = googleRegisterDto.Email,&lt;br&gt;
                UserName = googleRegisterDto.Username,&lt;br&gt;
                Us_Active = true,&lt;br&gt;
                Us_Customer = true,&lt;br&gt;
                Us_SubscriptionDays = 0&lt;br&gt;
            };&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If the user attempting to register is new and his records is not found in db. Then the above code will be executed and a user is created with role as just user. Note this line &lt;code&gt;var result = await _userManager.CreateAsync(user);&lt;/code&gt; will create a new user and save in db.&lt;/p&gt;

&lt;p&gt;Down this line,&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;if (result.Succeeded)&lt;br&gt;
            {&lt;br&gt;
                return `(user);&lt;br&gt;
            }&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 if everything goes well till now &lt;code&gt;CreateUserObject&lt;/code&gt; method will be called where a token will be generated for the user which will be used during his further interaction with app.&lt;/p&gt;

&lt;p&gt;Else, bad request with corresponding error message will be displayed as here &lt;code&gt;return BadRequest(result.Errors);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note- Here i used google login, which is most common for login these days. But, the underlying logic remains same for any other login mechanism.&lt;/p&gt;

&lt;p&gt;And finally, in the front end side in i have another reducer &lt;code&gt;signout&lt;/code&gt; as here&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;reducers: {&lt;br&gt;
        signOut: (state) =&amp;gt; {&lt;br&gt;
            state.user = null;&lt;br&gt;
            localStorage.removeItem('user');&lt;br&gt;
            router.navigate('/');&lt;br&gt;
        },&lt;br&gt;
        setUser: (state, action) =&amp;gt; {&lt;br&gt;
            const claims = JSON.parse(atob(action.payload.token.split('.')[1]));&lt;br&gt;
            const roles = claims['http://schemas.microsoft.com/ws/2008/06/identity/claims/role'];&lt;br&gt;
            state.user = {...action.payload, roles: typeof(roles) === 'string' ? [roles] : roles};&lt;br&gt;
        }&lt;br&gt;
    },&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 which can be triggered inside any component which is handling log out. In my case, i am using a menu component where i dispatch signout. You can use anywhere where you plan user to trigger logout. Once the &lt;code&gt;dispatch(signOut());&lt;/code&gt; from the component it will clear the localstorage as here &lt;code&gt;localStorage.removeItem('user');&lt;/code&gt; and user will be redirected to index page as here &lt;code&gt;router.navigate('/');&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To summarize:&lt;/strong&gt;&lt;br&gt;
Step-1 Front end- use any mechanism or package to decode the google token. Once decoded match its part as per the model or dto's defined in backend.&lt;br&gt;
Step-2 Send the request to backend via directly by axios or redux(centralized state management) using agent(which centralizes request to backend).&lt;br&gt;
Step-3 Once the endpoint in backend is hit, check if token id is valid and ensure it is issued by google only. If valid, then check if user record is already present in our db or not. If present, generate a token with minimum role as a user for further communication. If not then create a user and save its info on db and then generate token with minimum role for their further interaction with app.&lt;/p&gt;

&lt;p&gt;I hope this basic flow would be helpful to someone. Thanks for your time!&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>aspnet</category>
      <category>sqlserver</category>
    </item>
    <item>
      <title>Redux combineReducer</title>
      <dc:creator>Mannawar Hussain</dc:creator>
      <pubDate>Wed, 23 Sep 2020 06:25:47 +0000</pubDate>
      <link>https://dev.to/mannawar/redux-combinereducer-1mbc</link>
      <guid>https://dev.to/mannawar/redux-combinereducer-1mbc</guid>
      <description>&lt;p&gt;I am trying to get the concept of redux and understand how its bits and pieces are functioning. I would like to share my experience of learning combine Reducers precisely here.&lt;br&gt;
As per the docs of Redux there are three rules for combine Reducers.&lt;br&gt;
Link here &lt;a href="https://redux.js.org/api/combinereducers"&gt;https://redux.js.org/api/combinereducers&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For any action that is not recognized it must return state given to it as first argument. To elaborate this point, first we create a todos file under &lt;em&gt;reducer&lt;/em&gt; folder.
The content should be as below, this will switch action based upon action.type selected, and be sure to return default state otherwise eror &lt;b&gt;Error: Reducer "todos"/"counter" returned undefined during initialization&lt;/b&gt; will show:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return state.concat([action.text])
    default:
      return state
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;we next create another file called counter.js, content is as below, here we are also just incrementing and decrementing counter based upon the action.type. Here initia state is zero.:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function counter(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we will create another file combineReducer.js inside reducer folder whose content is as below, this one will first import combineReducers from redux library. combineReducers will take an object whose value is &lt;code&gt;{  todos: todos,&lt;br&gt;
  counter: counter&lt;br&gt;
}&lt;/code&gt;, as in ES6 syntax we can simply represent that as below :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { combineReducers } from 'redux'
import todos from './todos'
import counter from './counter'

export default combineReducers({
  todos,
  counter
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the most interesting part index.js or App.js where we will create store and will do dispatching action and console.logging. The content of which are as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createStore } from 'redux'
import combineReducers from './reducers/index'

const store = createStore(combineReducers)
console.log(store.getState());

//1.First argument is only returned
store.dispatch({
  type: 'ADD_TODO',
  text: 'This is the 1st argument from todos'
}, { type: 'DECREMENT'})

console.log(store.getState());

store.dispatch({
  type: 'INCREMENT'
})

console.log(store.getState());

store.dispatch({
  type: 'DECREMENT'
})

console.log(store.getState());

store.dispatch({
  type: 'DECREMENT'
})

console.log(store.getState());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In first line of code we imported createStore from redux library.&lt;br&gt;
For code under commented section-1, we give two parameters to store.dispatch, but it returns only as below:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g5VT8Mdy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/46415048/93972309-af78fa00-fd7a-11ea-92bf-a59d41ed292f.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g5VT8Mdy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/46415048/93972309-af78fa00-fd7a-11ea-92bf-a59d41ed292f.PNG" alt="first argument" width="670" height="365"&gt;&lt;/a&gt;&lt;br&gt;
Hence the rule, it must return the state given to it as first argument (only) is verified.&lt;/p&gt;

&lt;p&gt;Second rule states that it must never return undefined, to verify this we supplied empty object which returns undefined. Hence we can say that action type has to be there. If object with type empty string is supplied, the output will be undefined as below&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ExMFYuuZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/46415048/93973165-6a55c780-fd7c-11ea-8764-238ae2df7262.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ExMFYuuZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/46415048/93973165-6a55c780-fd7c-11ea-8764-238ae2df7262.PNG" alt="undefined" width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the third rule, if the state given to it is undefined or simply empty string or null the output will be carried from the previous state as below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XzY3TTyG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/46415048/93973608-2616f700-fd7d-11ea-9469-a1788349c67c.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XzY3TTyG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/46415048/93973608-2616f700-fd7d-11ea-9469-a1788349c67c.PNG" alt="sameState" width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ci01-G10--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/46415048/93974449-7e022d80-fd7e-11ea-996e-8b367bb59489.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ci01-G10--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/46415048/93974449-7e022d80-fd7e-11ea-996e-8b367bb59489.PNG" alt="Null" width="800" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you for your time.&lt;br&gt;
Happy Learning :)&lt;/p&gt;

</description>
      <category>redux</category>
      <category>react</category>
      <category>javascript</category>
      <category>middleware</category>
    </item>
  </channel>
</rss>
