[TinyERP]Angular for Enterprise Application – Multiple data-sources (Part 1)

0
20

Overview

If you want to checkout source-code used in this article. Please check it our from https://github.com/techcoaching/TinyERP (develop branch please)

In context of enterprise application, we may need to store data into various type of repositories due to different purpose:

  • Using relational database (such as: MSSQL, …) for validation data, frequently modified data, ….
  • Using multiple small databases instead of 1 big database in enterprise system. Such as: database for order module, database for product management module, database for customer management module, ….
  • Using NoSQL (such as: MongoDB, RavenDb, …) for fast reading.
  • Using Elastic for searching data.

We will go through these as below.

Using single relational database (such as: MSSQL, … for validation data, frequently modified data)

This is traditional solution that was used for storing data of our system.

For example with simple requirement: User will fill in the form with user information (such as: first name, last name, email) and click on submit for creating new user. Then user can view this information of user.

Photo below describes how the flow will be:

For creating new users:

  • UserController: receive request from user with information of new user will be created
  • UserService: Validate data passed from UserController and call UserRepository if data was ok.
  • UserRepository: create new instance of DbContext (in EntityFramework) and insert new user into database.

For getting user information:

  • UserController: Receive get request from user and pass to UserRepository
  • UserRepository: Get data and return to client.

Let check how to implement this in TinyERP.

For creating new users

In UsersController:

namespace App.Api.Features.Security
{
 [RoutePrefix("api/users")]
 public class UsersController : BaseApiController
 {
 [HttpPost()]
 [Route("")]
 [ResponseWrapper()]
 public CreateUserResponse CreateUser([FromBody]CreateUserRequest request)
 {
 IUserService userService = IoC.Container.Resolve<IUserService>();
 return userService.CreateUser(request);
 }
 }
}

CreateUserRequest class:

public class CreateUserRequest
{
 public string Email { get; set; }
 [Required("security.addOrUpdateUser.validation.firstNameIsRequire")]
 public string FirstName { get; set; }
 [Required("security.addOrUpdateUser.validation.lastNameIsRequire")]
 public string LastName { get; set; }
}

There is “Require” attribute for “FirstName” and “LastName” properties, these attributes were used for validation in UserService class. We will not focus in this article at the moment.

And CreateUserResponse class:

public class CreateUserResponse: IMappedFrom<App.Entity.Security.User>
{
 public Guid Id { get; set; }
 public string FistName { get; set; }
 public string LastName { get; set; }
 public DateTime CreatedDate { get; set; }
}

UserService class:

internal class UserService : IUserService
{
 public CreateUserResponse CreateUser(CreateUserRequest request)
 {
 this.ValidateCreateUserRequest(request);
 using (IUnitOfWork uow = new App.Common.Data.UnitOfWork(RepositoryType.MSSQL))
 {
 User user = new User(request.Email, string.Empty, request.FirstName, request.LastName);

 IUserRepository userRepository = IoC.Container.Resolve<IUserRepository>(uow);
 userRepository.Add(user);
 uow.Commit();

 return ObjectHelper.Convert<CreateUserResponse>(user);
 }
 }

 private void ValidateCreateUserRequest(CreateUserRequest request)
 {
 IValidationException validationException = ValidationHelper.Validate(request);
 if (!EmailHelper.IsValid(request.Email))
 {
 validationException.Add(new ValidationError("security.addOrUpdateUser.validation.invalidEmail"));
 }
 validationException.ThrowIfError();
 }
}
 

This sample code uses default DbContext as defined  in App.Api/Features/Common/DbContextResolver” class.

Some case, you want to specify your own DbContext, look at “Using multiple small databases instead of 1 big database in enterprise system” for more information (in part 2 of this article).

 In this class, we create new instance of UnitOfWork, that will insert data into MSSQL using:

using (IUnitOfWork uow = new App.Common.Data.UnitOfWork(RepositoryType.MSSQL))

and create new instance of User class:

User user = new User(request.Email, string.Empty, request.FirstName, request.LastName);

And insert into appropriated repository (UserRepository):

 IUserRepository userRepository = IoC.Container.Resolve<IUserRepository>(uow);
userRepository.Add(user);
uow.Commit();

The last command will convert newly created User object to CreateUserResponse and return to client:

return ObjectHelper.Convert<CreateUserResponse>(user);

We can see that, it is really simple to insert data into MSSQL. We can also insert data into other database (such as: MOngoDb) by the following command:

using (IUnitOfWork uow = new App.Common.Data.UnitOfWork(RepositoryType.MongoDB))

We will discuss more detail about this later in this article.

About validation, We can use validation attribute, such as, “Require” in CreateUserRequest above and using this line of code for validate that object:

IValidationException validationException = ValidationHelper.Validate(request);

Or manual validate yourself and add new ValidationError into IValidationException object:

if (!EmailHelper.IsValid(request.Email))
{
 validationException.Add(new ValidationError("security.addOrUpdateUser.validation.invalidEmail"));
}

Let try to run the api and send request for creating new user:

And response from server for creating new user:

Check data in Database, we see the result:

 For getting user information:

Just add new method into UsersController:

[HttpGet()]
[Route("{userId}")]
[ResponseWrapper()]
public UserSummary GetUser([FromUri]Guid userId)
{
 IUserRepository userRepo = IoC.Container.Resolve<IUserRepository>();
 return userRepo.GetById<UserSummary>(userId.ToString());
}

It is simple to call GetById from UserRepository. UserSummary as below:

public class UserSummary: BaseEntity, IMappedFrom<App.Entity.Security.User>
{
 public string Email { get; set; }
 public string FirstName { get; set; }
 public string LastName { get; set; }
}

Calling to this API from REST client, we have the result as:

For now, We can see it is simple to insert or get data from MSSQL. Let continuing with “Using multiple small databases instead of 1 big database in enterprise system”

 For more information about other articles in this series

Thank you for reading,

Note: Please like and share to your friends if you think this is usefull article, I really appreciate

LEAVE A REPLY