Creating CRUD using CQRS Pattern (part 2)

Last week, in order to create a Create command for an entity, I first needed to create four components: CreateCommand, CreateCommandHandler, CreateCommandResponse, and CreateCommandValidator.

CreateCommand represents the command itself and contains all the necessary data required to create a new entity in the system, including things like the entity’s name, description, and other important details. This was where I also learned something new about using a question mark when defining a property (e.g., public int? Age { get; set; }). The “?” symbol allows the property to be set to null if no information is available.

Next, I created the CreateCommandHandler, which is responsible for handling the CreateCommand and performing the necessary actions to create the entity in the system. It receives the CreateCommand, validates the data, and creates the entity in the appropriate data store. This part of the code (CreateCommandHandler) was challenging for me because I wasn’t sure what code to write, but Mr. Peter helped me understand by using an example from a previous entity. He also pointed out that my difficulty was due to not fully grasping OOP principles.

Then, there’s the CreateCommandResponse, which is the component returned by the CreateCommandHandler after the entity has been successfully created. It contains the ID or other relevant information about the newly created entity. Moving on to next week, I’ll be continuing on creating another component named CreateCommandValidator, which is responsible for validating the data in the CreateCommand before it is processed by the CreateCommandHandler. This component ensures that the data is in the correct format and meets any required constraints.

Together, these four components create a system that is capable of creating new entities within a CQRS-based system. CreateCommand encapsulates all the necessary data, CreateCommandHandler creates the entity, CreateCommandResponse provides information about the newly created entity, and CreateCommandValidator ensures that the data is valid before it is processed.

Creating CRUD using CQRS Pattern (part 1)

This week marked the beginning of my opportunity to apply the knowledge that I gained from the courses that I learnt from the previous weeks. Mr. Peter gave me my first task: creating CRUD for an entity using CQRS pattern. However, before diving into the task at hand, it was necessary to set up the environment by launching the SandBox app, which Mr. Peter graciously guided me through. This included various debugging processes essential for successfully launching the system. First, I needed to create a database and import the existing tables into it. Then, cloned a git repository from an existing repository named Sandbox(which is the main solution used for trying out new features first before implementing it on a real application). There’s also another repo for context and modules under the main repository where this is the first I discover that there can be more repositories created under an existing git repository. 

Launching the Sandbox app took quite some time as there’s a bit of debugging needed which most of it was solved by Mr Peter. One of the issues that arose was due to my carelessness in setting up the credentials of the API. I unwittingly included a space in a word that was not supposed to have one, causing the issue of invalid authentication. From this experience, I learned a valuable lesson that even the slightest error, such as a space, can cause significant time wastage during debugging. As a result, I now realize the importance of paying attention to the smallest of details. 

Throughout the week when I’m completely lost on what to and what should I debug, I instead just go through the codes from an existing project to guide me through creating the CRUD for an entity while also watching the courses again to have deeper understanding on how the code works. Moreover, I learned about a new git method known as git stash, which allows you to temporarily shelve changes you’ve made to your working copy so that you can work on something else and then re-apply them later. When it came time to create the CRUD for the entity, I initially created all folders and pages at once for creating, updating, deleting, and getting information. However, Mr. Peter advised that it would be best to create them one by one and test each unit immediately to ensure the stability of the code before moving on to the next feature.

Overall, I am grateful for the opportunity to learn from Mr. Peter this week. While I feel that I did not make significant progress personally, I am eager to continue learning and growing. I look forward to the challenges that lie ahead, particularly in creating the CRUD for an entity next week.

Exploring Test case (Part 2)

Hello there, I hope all is okay with you. As part of my task last week, I worked on writing a test case for the “Name Display” feature during the login process. Here is a brief summary of what I accomplished. After I already get helped from Peter, Peter show me to write test script well written without any errors.

Next, continue with this week task. For this week, I continue to explore on the test script. About the task, Peter showed me on how to use test timer with beforeEach and afterEach. By using describe function used to group together related test cases with a common name which is “Test Timer”. The beforeEach function is a Jest lifecycle hook that specifies setup step that should be executed before each test case in the test suite. For this case, it is using “jest.useFakeTimers” with the “advanceTimers” option set to true. This will allow Jest to replace the real timers in the environment with fake timers that can be controlled programmatically in the test cases. It also calls “jest.resetModules()” to reset any modules that may have been cached by Jest, ensuring a clean state before each test.

Furthermore, for the first test which is “Display user name if not logged in”. It renders component with props.navigation and props.route as props. It then uses the “getByTestId” function to get the component is equal to the expected string. Second test which is “Display correct user name when logged in”. It renders component with props.navigation and props.route as props using the render function. It then calls jest.advanceTimersByTime to advance the timers. It asserts that the props.children of the retrieve component is equal to the expected string “Welcome, ${displayName} !”.

Exploring Test case (Part 1)

Hey there, I hope you are doing well. It is time for my weekly work update, highlighting the progress I made during past week. As part of my tasks last week, I worked on writing a test case for the “Name Display” feature during the login process. Here is a brief summary of what I do: For the test case task, Peter told me to write a test case to verify that after logging in, going back to the home screen, reopening the app, and pressing login without retyping login credentials, the correct name displayed. There also several test case file for the references.

At first I try to figure out what to write, after I refer to the another test file, it open my eyes on how to write the test script. After I already finished write the test script, then I try to run the test. At first the result for the test is fail, then I try to look back on what that make it is failed. It is cause from the “testID” that make the test script keep failed. I try to figure out on how to solve the error by Google and explore the other file that have the test script. After several tries and it still keep showing the test script is fail and not pass.

ASP.Net Core and RESTful API

Last week, I had the opportunity to learn the architecture of ASP.NET Core 3. The first part of the course I was exposed to the importance of separating concerns in an application by organizing code into layers, including the presentation layer, application layer, domain layer, and infrastructure layer. Additionally, I also explored how to implement clean architecture in ASP.NET Core 3 applications, including how to structure the code and how to use interfaces and dependency injection to decouple components so that the code easier to maintain for future usage.

Going to the next part, I started to delved into Automapper, a powerful tool that can simplify the process of mapping data between different objects in the application. I learned how to install and configure Automapper in ASP.NET Core 3 application, and how to use it to map data between entities and DTOs (data transfer objects). Next, a design pattern known as CQRS (Command Query Responsibility Segregation), which divides the duties of managing read and write operations in an application, was the next area of emphasis for me. At first, I struggled to understand the CQRS concept, but Mr. Peter clarified it for me, helping me to understand the idea of it as a whole. I learned about the benefits of CQRS, including how it improved scalability and performance. I even also explored how to use MediatR, a popular library for implementing CQRS in .NET applications.

After few days going through the architecture of ASP.NET, the next 2 and a half day of the week I started to go through a new topic called “Building a RESTful API with ASP.NET Core 3”. I learned about the difference between the Outer Facing Model and the Entity Model. The Outer Facing Model represents the data that will be exposed to clients through the API, while the Entity Model represents the data that is stored in the database. the course also taught on how to map between these two models, and how to use Automapper to simplify the process.

Another key aspect of building a RESTful API is handling HTTP requests, including POST, PUT, and PATCH requests. I learned the differences between these requests and how to handle them in an API. I also explored how to use data annotations and custom validators to validate user input, which is critical for ensuring the integrity of data. Finally, the course covered how to delete a resource in an API, including how to handle deleting a single and related resources in the database.

Overall, the past week learning is quite complex for me. I did gained the understanding of the whole concept and idea of the materials but in term of practicality and codes, I must say I’m still very weak. However, I really look forward on exploring more on these topics and gaining deeper understanding on implementing the knowledge of the ASP.NET architecture and building the RESTful API.

About the Application

Last week, Peter introduced to me an application that we use in Tong Hin. Briefly describe about the code that used in this application, It is use a React Native component that implements a login view for an app using the OAuth 2.0 authorization framework. It allows users to log in with a provider, in this case, obtains an access token and an ID token that can be used to authenticate the user’s identity and access protected resources on behalf of the user.

It’s imports libraries such as AsyncStorage, react-native-paper, and react-native-app-auth to implement functionalities such as token storage, UI components, and OAuth 2.0 authorization. The AppContext is used to share data between components, and screens in the app.

Next, it’s also defines the configuration for the authorization provider that will be used for the OAuth 2.0 authorization. The provider’s issuer, client ID, redirect URL, and etc are specified, as well as the scopes that the app requires access to.

Finally, defines the default state of the authentication, which includes information such as whether the user has logged in, which provider was used, and the tokens obtained from the authorization process.

EF Core 5

In my second week at Tong Hin, I started up by studying object-oriented programming (OOP) and learnt that OOP is a programming paradigm that is widely used in C#. It is a way of programming that focuses on creating objects that interact with each other to accomplish tasks. In OOP, objects are created from classes, which define their properties and behaviors.

The main concepts of OOP in C# include encapsulation, inheritance, and polymorphism. Encapsulation is the practice of hiding data and methods within an object, so that they cannot be accessed from outside the object. As for Inheritance is a concept that allows classes to inherit properties and methods from other classes where inheritance creates a hierarchy of classes, with each class having a parent class, except for the root class, which has no parent. Inheritance also enables developers to create new classes based on existing classes (parent class). Thus, reducing code duplication and promoting code reuse. The derived class inherits all the properties and methods of the parent class, and can also add new properties and methods.

Later on the same week, I started to go through another module which is Entity Framework (EF), it is an object-relational mapping (ORM) framework for .NET applications that provides a simplified approach to working with databases, and the latest version, Entity Framework Core 5 (EF Core 5), offers several new features and improvements compared to the earlier versions. When I first started learning Entity Framework, I was impressed by its ability to simplify data access by mapping database tables to classes and providing a LINQ-based query syntax. EF made it easy to create, read, update, and delete records in a database without needing to write complex SQL statements. I also learnt that EF Core is cross-platform support where it can run on multiple operating systems, including Linux and macOS. This makes it easier to develop and deploy applications on a wider range of platforms. 

Another significant feature in EF Core 5 is its support for multiple databases. While EF only supports Microsoft SQL Server, EF Core 5 supports a variety of databases, including PostgreSQL, MySQL, SQLite, and more. As a result, working with various data sources is made simpler without the need to learn additional frameworks or languages.

Overall, EF Core 5 is a valuable tool for developers who need to work with data in .NET applications. It simplifies the process of data access and provides a range of features to enhance performance and improve developer productivity.