Skip to content

Latest commit

 

History

History

MyEf.Hr

MyEf.Hr

The purpose of this sample is to demonstrate the usage of Beef (and CoreEx runtime) within the context of a fictitious Human Resources solution. The main intent is to show how Beef can be used against a relational database (SQL Server) leveraging only Entity Framework (EF).

Also, it will demonstrate how the data can be shaped differently between the database and the entity to leverage both relational and object-oriented constructs to provide a natural consuming experience from the API that accounts for the object-relational impedence mismatch.

This sample will walkthrough an approach of adding the capabilities in a series of logical steps, versus big-bang (all at once), as this is more typical of how a developer may implement.


Beef composition

Beef is ostensibly the code-generation engine that ultimately takes dependencies on the following capabilities to enable the end-to-functionality and testing thereof:

  • CoreEx - provides the core runtime capabilties (extends .NET core);
  • UnitTestEx - provides extended unit and intra-domain integration testing;
  • DbEx - provides extended database management capabilties;
  • OnRamp - provides the underlying code-generation engine functionality.

Scope

Within the sample there will two primary entities exposed:

  • Employee - being an employee that either is, or was, employed by the ficticous organization.
  • Performance Review - being a recording of a number of performance reviews for an employee over time.

Employee

This will represent an employee within the organization, and house key data such as their name, address, phone number, gender, date of birth, start and termination dates, and a list of up to five emergency contacts.

From an endpoint perspective it will support the following.

Endpoint Description
GET /employees/id Get employee by primary identifier.
POST /employees Create a new employee.
PUT /employees/id Update (replace) the existing employee (only where not terminated).
PATCH /employees/id Patch the existing employee (only where not terminated).
DELETE /employees/id Delete an existing employee (only where not started).
GET /employees Gets employee(s) that match the selection criteria (a subset of the fields to be returned, plus support for paging).
POST /employees/id/terminate Updates the employee as terminated (other endpoints do not allow termination).

Performance Review

This will respresent a performance review (multiple over time), and house key data such as date, outcome, notes and reviewer.

From an endpoint perspective it will support the following.

Endpoint Description
GET /reviews/id Get review by primary identifier.
POST /employees/id/reviews Create a review for a specified employee.
PUT /reviews/id Update (replace) the review.
PATCH /reviews/id Patch the existing review.
DELETE /reviews/id Delete an existing review.
GET /employee/id/reviews Gets all review(s) for the employee (with paging support).

Railway-oriented programming

CoreEx version 3.0.0 introduced monadic error-handling, often referred to as Railway-oriented programming. This is enabled via the key types of Result and Result<T>; please review the corresponding documentation for more detail on purpose and usage.

The Result and Result<T> have been integrated into the code-generated output and is leveraged within the underlying validation. This is intended to simplify success and failure tracking, avoiding the need, and performance cost, in throwing resulting exceptions.


Core Implementation steps

As described earlier, this sample will walk through the implementation in a number of logical steps:

  1. Solution Skeleton - start by creating a VS solution from Beef template
  2. Employee DB - creates the Employee database table and related entity framework capabilities.
  3. Employee API - creates the Employee entities, API and related data access logic.
  4. Employee Test - creates the Employee end-to-end integration tests to validate the API and database functionality.
  5. Employee Search - adds the Employee search capability and tests.
  6. Employee Terminate - adds the Employee termination capability and tests.
  7. Employee Performance Review - adds the employee PerformanceReview capability end-to-end, from the the database, through the APIs and corresponding testing.

Event Driven Architecture implementation

The implementation so far has created the API capabilities to perform operations on the data as originally defined in the scope. This section can be skipped where the related Event-driven architecture capabilities are not required.

However, to further support the goals of an Event-driven architecture (EDA) both the publishing and subscribing of events is required, and will be largely enabled leveraging the CoreEx.Events capabilities.


Conceptual architecture

The Conceptual Architecture for the solution including eventing/messaging is as follows:

Architecture

The Architecture is composed of the following components:

  • API - represents the HR domain API-endpoint;
  • SQL - represents the HR domain data and outbox repository;
  • Relay - represents the HR domain Azure Service Bus publishing relay;
  • Subscriber - represents the Security domain Azure Service Bus subscriber;
  • OKTA - represents the external OKTA Identity Management API-endpoints (for Employee User Accounts).
  • Event-stream - represents the Azure Service Bus capabilities.

The data-flow represented is related to an Employee Termination; in that an Employee's User Account will be automatically deactivated within OKTA as a result of their termination.

The HR and Security domains are completely decoupled from each other; in that there is no run-time dependency between them - they only communicate via messages in near-realtime as enabled by the event-stream.


Additional implementation steps

This EDA sample will walk through the implementation in a number of logical steps (these describe the integration of the CoreEx capabilities to enable) to achieve the end-to-end Employee's User Account deactivation:

  1. Transactional Outbox - enqueue events into the database.
  2. Service Bus Publish - dequeue events (relay) from database publishing to Azure Service Bus.
  3. Service Bus Subscribe - simulate an additional domain subscribing to an event (from Azure Service Bus).

Conclusion

The basis of the functional capabilities have been created for our fictitious solution. In the end, the developer should have a reasonable understanding of how to build a relatively complicated back-end (API and database) solution leveraging Beef as the code-generator, and CoreEx as the extended runtime.

The developer should have witnessed that reasonably complicated logic can be built using this config to code-gen to custom approach. Where the custom effort is for the most part focused on the key business value delivery; not the related boilerplate. Plus, with the UnitTestEx testing framework, how complex end-to-end intra-domain integration tests can be created to appropriately validate the underlying logic - which can easily be integrated into the developer build-test-release lifecycle.

It is acknowledged that there is a learning curve required for using Beef et al; and in time greater acceleration will be achieved as experience is gained. Please review the extended documentation and provide feedback, questions, defects, etc. via an issue to any of the repos.

Thanks and enjoy :-)