Coder Social home page Coder Social logo

nox's Introduction

Nugetcontributorsissuesstarsbuildforks



Logo

Build and deploy enterprise-grade business solutions in under an hour


Table of Contents
  1. About
  2. Main Features
  3. Contributing to the Nox library
  4. Using the Nox Library

About

Nox.Lib is a .NET framework that allows developers to rapidly build, maintain and deploy enterprise-grade, production-ready business solutions.

💡 At its heart, Nox is a code scaffolding engine that is extended through a range of handlers, including message, command, query and event handlers.

Nox pivots around the concept of a solution definition. This solution describes the domain, application, integrations, infrastructure, version control and project team. The Nox.Generator interprets this solution and scaffolds all the necessary code for a working solution.

Main Features

  • Declaration of your core application and domain (models, data, entities, attributes and bounded contexts) in a declaritive and easily maintainable way (YAML, using YamlDotNet).
  • Automatic (and selective) Create, Read, Update and Delete (CRUD) API for entities and/or aggregate roots (supports REST with OData, with GraphQL and gRPC in the making).
  • The choice of persisting your data in any database with current support for Sql Server, PostgreSQL or MySql (using Entity Framework).
  • Automated Database Migrations (coming soon).
  • Validation of entities and attributes (using FluentValidation).
  • Logging, Observability and Monitoring (using SeriLog).
  • Events and Messaging (In process/Mediator, Azure Servicebus, Amazon SQS, RabbitMQ) using MassTransit.
  • Extract, transform and load (ETL) definitions from any database, file or API with bulk-load and merge support.
  • A task scheduler for running recurring tasks at periodic intervals (using Hangfire).
  • Automated DevOps including testing and deployment.
  • Nox.Yaml is a dotnet standard wrapper to YamlDotnet that takes the pain out of using YAML configuration files for your projects.

Contributing to the Nox library

We welcome community pull requests for bug fixes, enhancements, and documentation. See How to contribute for more information.

Local Development

To run the SampleWebApp you need to have SQL Server running. This is a temporary measure until support for MySQL and PostreSQL is implemented.

In the root of your project start SQL Server in a Docker container by running docker-compose -f .\docker-compose.sqlServer.yml up

Update database with migrations by running the command dotnet ef database update -c "SampleWebAppDbContext"

Run the Sample the database should be provisioned and properly setup its model.

Update the Database Model

Migration history do not need to be tracked, usually during local development you can delete 'Migration' folder and create a new migration.

If you don't have .NET EF Core Tools installed, run dotnet tool install --global dotnet-ef at the command line. You'll also need to add EF Core Design to your project to run migrations. Simply run dotnet add package Microsoft.EntityFrameworkCore.Design.

To generate initial migration you can use the following command dotnet ef migrations add "InitialCreate" -c "SampleWebAppDbContext"

Odata

OData endpoints in debug mode can be found at \$odata

[Nox.Solution] Updating Schemas

Until this process is automated, whenever a new TypeOption is added to the Nox Solution the following steps must be followed:

  1. Add your new type to class NoxSimpleTypeDefinition inside the #region TypeOptions;
  2. Run the test in NoxSolutionSchemaGenerate, this test will generate the new schema files;
  3. Add and commit changed .json schema files to the solution.

[Nox.Types] ToString conventions

Nox does not follow the usual convention for ToString().
The ToString() method should return the same result independently of the current culture, for example for DateTime, Currency, dependent types.
The reasoning behind this is to ensure a fully predictable result that facilitates ETL processes and interoperability with other systems.
The same is expected for the ToString(string format) overload.
If you need a culture dependent representation create an overload with a IFormatProvider parameter, example:

ToString(IFormatProvider formatProvider);

LatLong Nox.Type example:

public override string ToString()
{
    return $"{Value.Latitude.ToString("0.000000", CultureInfo.InvariantCulture)} {Value.Longitude.ToString("0.000000", CultureInfo.InvariantCulture)}";
}

public string ToString(IFormatProvider formatProvider)
{
    return $"{Value.Latitude.ToString(formatProvider)} {Value.Longitude.ToString(formatProvider)}";
}

Versioning

We are using SemVer for versioning our deliverables.

To manage this version we are using GitVersion tool.

Using it locally

You can use gitversion locally to test and setup configuration. To do that intall the dotnet tool dotnet tool install --global GitVersion.Tool --version 5.*

Run dotnet-gitversion to see the current variables of git version

Run dotnet-gitversion /updateprojectfiles to update csproject files

Release

Create a release in GitHub and tag it properly. In the future we want to automate this process.

Using the Nox Library

Environment Variables for Sensitive Data

Do not commit or keep sensitive data on your yaml solution files.
The current way to this is by using Environment Variables.

Example

Nox will expand any text with the following convention ${{ env.VAR_NAME }} to the value of VAR_NAME Environment Variable if found. Sample Yaml:

databaseServer:
name: SampleCurrencyDb
serverUri: ${{ env.DB_SERVER }}
provider: sqlServer
port: 1433
user: ${{ env.DB_USER }}
password: ${{ env.DB_PASSWORD }}

Query and Command Extensibility

Security and other Validations

To add security, or other business rules to generated/custom queries or commands, add an IValidator interface for the query. See the example below for securing GetStoreByIdquery

public class GetStoreByIdSecurityValidator : AbstractValidator<GetStoreByIdQuery>
{
    public GetStoreByIdSecurityValidator(ILogger<GetStoreByIdQuery> logger)
    {
        // For the Current User
        // TODO Get Stores that he can see.... 

        // Do Validation The current user can only see EUR Store
        RuleFor(query => query.key).Must(key => key == "EUR").WithMessage("No permissions to access this store");            
    }
}

The validator will be excuted before the request. Adding the validator to the service collection as per the code snippet below should yield a ValidationException at runtime:

services.AddSingleton<IValidator<Queries.GetStoreByIdQuery>, GetStoreByIdSecurityValidator>();

Queries Filter Extension

To add extra filter to generated queries, for security or other purposes, add a new Pipeline behavior (see MediatR), filtering Get Stores example:

public class GetStoresQuerySecurityFilter : IPipelineBehavior<GetStoresQuery, IQueryable<OStore>>
{
    public async Task<IQueryable<OStore>> Handle(GetStoresQuery request, RequestHandlerDelegate<IQueryable<OStore>> next, CancellationToken cancellationToken)
    {
        var result = await next();

        return result.Where(store => store.Id == "EUR");
    }
}

And register in the container:

services.AddScoped<IPipelineBehavior<GetStoresQuery, IQueryable<OStore>>, GetStoresQuerySecurityFilter> ()

Add new Queries to Existing Controllers

To add a custom query to a generated controller, you need to:

  1. Create a partial class with the name of the controller
  2. Create a Query Request
  3. Create a Query Handler

Example:

/// <summary>
/// Extending a OData controller example with additional queries (Action) and commands (Functions)
/// </summary>
public partial class CountriesController
{
    [HttpGet("GetCountriesIManage")]
    public async Task<IResult> GetCountriesIManage()
    {
        var result = await _mediator.Send(new GetCountriesIManageQuery());
        return Results.Ok(result);
    }
}


namespace SampleWebApp.Application.Queries
{
    /// <summary>
    /// Custom Query and Handler Example
    /// </summary>
    public record GetCountriesIManageQuery : IRequest<IQueryable<OCountry>>;

    public class GetCountriesIManageQueryHandler : IRequestHandler<GetCountriesIManageQuery, IQueryable<OCountry>>
    {
        public GetCountriesIManageQueryHandler(ODataDbContext dataDbContext)
        {
            DataDbContext = dataDbContext;
        }

        public ODataDbContext DataDbContext { get; }

        public Task<IQueryable<OCountry>> Handle(GetCountriesIManageQuery request, CancellationToken cancellationToken)
        {
            return Task.FromResult((IQueryable<OCountry>)DataDbContext.Countries.Where(country => country.Population > 12348));
        }
    }
}

Generated API

The endpoints below are generated to manage CRUD operations for Entity (e.g. Country), its related and owned entities.

Entity endpoints

GET /api/<EntityPluralName> (e.g. /api/Countries)
  • Description: Retrieves a list of entities (e.g. countries). OData query is enabled for this endpoint.
  • Query Parameters: None
  • Response: Returns a queryable collection of <Entity>Dto (e.g. CountryDto) objects.
GET /api/<EntityPluralName>/<key> (e.g. /api/Countries/1)
  • Description: Retrieves a specific entity (e.g. country) by ID. OData query is enabled for this endpoint.
  • Path Parameters: <key>: ID of the entity to retrieve.
  • Response: Returns a single queryable <Entity>Dto (e.g. CountryDto) object.
POST /api/<EntityPluralName> (e.g. /api/Countries)
  • Description: Creates a new entity (e.g. country).
  • Request Body: <Entity>CreateDto (e.g. CountryCreateDto) object. Owned entities: <Entity>CreateDto contains <OwnedEntity>UpsertDto (e.g. CountryLocalNameUpsertDto) property to create new owned entity. Related entities: <Entity>CreateDto contains <RelatedEntity>Id (e.g. TimeZoneId) property to create a reference between new entity and existing related entity.
  • Response: Returns the newly created <Entity>Dto (e.g. CountryDto) object.
PUT /api/<EntityPluralName>/<key> (e.g. /api/Countries/1)
  • Description: Updates an existing entity (e.g. a country) by ID.
  • Path Parameters: <key>: ID of the entity to update.
  • Request Body: <Entity>UpdateDto (e.g. CountryUpdateDto) object.
    • Owned entities: Since an entity can have a to-one or to-many relationship to owned entitites, there are some behaviors that need to be considered when invoking this endpoint.
      • To-one owned entity relationship:
        • If the owned entity property is unspecified or set as null, owned entity will be deleted.
        • Otherwise, owned entity will be updated according to the provided data.
      • To-many owned entity relationship:
        • If the owned entity property has new owned entity entries that don't exist on the entity, new owned entities will be added.
        • If the owned entity property has fewer entries than the entity, owned entities that were not provided will be deleted.
        • If the owned entity property is set as an empty collection, all owned entities will be deleted.
        • If the owned entity property is unspecified of set as null, no changes will be applied.
        • Otherwise, owned entities will be updated according to the provided data.
    • Related entities: <Entity>UpdateDto does not contains related entity properties.
  • Response: Returns the updated <Entity>Dto (e.g. CountryDto) object.
PATCH /api/<EntityPluralName>/<key> (e.g. /api/Countries/1)
  • Description: Partially updates an existing entity (e.g. a country) by ID.
  • Path Parameters: <key>: ID of the entity to partially update.
  • Request Body: Delta<<Entity>PartialUpdateDto> (e.g. Delta<CountryPartialUpdateDto>) object. Owned entities: Delta<<Entity>PartialUpdateDto> does not contains owned entity properties. Related entities: Delta<<Entity>PartialUpdateDto> does not contains related entity properties.
  • Response: Returns the updated <Entity>Dto (e.g. CountryDto) object after partial update.
DELETE /api/<EntityPluralName>/<key> (e.g. /api/Countries/1)
  • Description: Deletes a specific entity (e.g. country) by ID.
  • Path Parameters: <key>: ID of the entity to delete.
  • Response: Returns a status code indicating success or failure.

Owned Entities endpoints

The following endpoints are generated based on relationship => apiGenerateRelatedEndpoint yaml configuration.

GET /api/<EntityPluralName>/<key>/<OwnedEntityName> (e.g. /api/Countries/1/CountryLocalNames)
  • Description: Retrieves owned entities (e.g. CountryLocalNames) associated with a specific entity (e.g. country). OData query is enabled for this endpoint.
  • Path Parameters: <key>: ID of the entity.
  • Response: Returns a queryable collection of <OwnedEntity>Dto (e.g. CountryLocalNameDto) objects.
GET /api/<EntityPluralName>/<key>/<OwnedEntityName>/<relatedKey> (e.g. /api/Countries/1/CountryLocalNames/1) - for zeroOrMany/oneOrMany relationships only
  • Description: Retrieves a specific owned entity (e.g. CountryLocalName) associated with a specific entity (e.g. country) by ID. OData query is enabled for this endpoint.
  • Path Parameters: <key>: ID of the entity. <relatedKey>: ID of the owned entity.
  • Response: Returns a single queryable <OwnedEntity>Dto (e.g. CountryLocalNameDto) object.
POST /api/<EntityPluralName>/<key>/<OwnedEntityName> (e.g. /api/Countries/1/CountryLocalNames)
  • Description: Creates a new owned entity (e.g. CountryLocalName) for the existing entity (e.g. country).
  • Path Parameters: <key>: ID of the entity.
  • Request Body: <OwnedEntity>UpsertDto (e.g. CountryLocalNameUpsertDto) object.
  • Response: Returns the newly created <OwnedEntity>Dto (e.g. CountryLocalNameDto) object.
PUT /api/<EntityPluralName>/<key>/<OwnedEntityName> (e.g. /api/Countries/1/CountryLocalNames)
  • Description: Updates or creates an owned entity (e.g. CountryLocalName) for the existing entity (e.g. country) by ID.
  • Path Parameters: <key>: ID of the entity to update.
  • Request Body: <OwnedEntity>UpsertDto (e.g. CountryLocalNameUpsertDto) object.
  • Response: Returns the updated or created <OwnedEntity>Dto (e.g. CountryLocalNameDto) object.
PATCH /api/<EntityPluralName>/<key>/<OwnedEntityName> (e.g. /api/Countries/1/CountryLocalNames)
  • Description: Partially updates an owned entity (e.g. CountryLocalName) for the existing entity (e.g. country) by ID.
  • Path Parameters: <key>: ID of the entity to update.
  • Request Body: Delta<<OwnedEntity>UpsertDto> (e.g. Delta<CountryLocalNameUpsertDto>) object.
  • Response: Returns the updated <OwnedEntity>Dto (e.g. CountryLocalNameDto) object after partial update.
DELETE /api/<EntityPluralName>/<key>/<OwnedEntityName>/<relatedKey> (e.g. /api/Countries/1/CountryLocalNames/1) [only for zeroOrMany/oneOrMany relationships]
  • Description: Deletes a specific owned entity (e.g. CountryLocalName) associated with a specific entity (e.g. country) by ID.
  • Path Parameters: <key>: ID of the entity. <relatedKey>: ID of the owned entity.
  • Response: Returns a status code indicating success or failure.

Related Entities endpoints to manage the related entity

The following endpoints are generated based on relationship => apiGenerateRelatedEndpoint yaml configuration.

GET /api/<EntityPluralName>/<key>/<RelatedEntityPluralName> (e.g. /api/Countries/1/TimeZones)
  • Description: Retrieves all related entities (e.g. time zones) associated with a specific entity (e.g. country). OData query is enabled for this endpoint.
  • Path Parameters: <key>: ID of the entity.
  • Response: Returns a queryable collection of <RelatedEntity>Dto (e.g. TimeZoneDto) object.
GET /api/<EntityPluralName>/<key>/<RelatedEntityPluralName>/<relatedKey> (e.g. /api/Countries/1/TimeZones/1) [only for zeroOrMany/oneOrMany relationships]
  • Description: Retrieves a specific related entity (e.g. time zone) associated with an entity (e.g. country) by ID. OData query is enabled for this endpoint.
  • Path Parameters: <key>: ID of the entity. <relatedKey>: ID of the related entity.
  • Response: Returns a single queryable <RelatedEntity>Dto (e.g. TimeZoneDto) object.
POST /api/<EntityPluralName>/<key>/<RelatedEntityPluralName> (e.g. /api/Countries/1/TimeZones)
  • Description: Creates new related entity (e.g. time zone) associated with an existing entity (e.g. country).
  • Path Parameters: <key>: ID of the entity.
  • Request Body: <RelatedEntity>CreateDto (e.g. TimeZoneCreateDto) object.
  • Response: Returns the newly created related entity <RelatedEntity>Dto (e.g. TimeZoneDto) object.
PUT /api/<EntityPluralName>/<key>/<RelatedEntityPluralName>/<relatedKey> (e.g. /api/Countries/1/TimeZones/1)
  • Description: Updates a specific related entity (e.g. time zone) associated with an entity (e.g. country) by ID.
  • Path Parameters: <key>: ID of the entity. <relatedKey>: ID of the related entity.
  • Request Body: <RelatedEntity>CreateDto (e.g. TimeZoneCreateDto) object.
  • Response: Returns the updated related entity <RelatedEntity>Dto (e.g. TimeZoneDto) object.
DELETE /api/<EntityPluralName>/<key>/<RelatedEntityPluralName>/<relatedKey> (e.g. /api/Countries/1/TimeZones/1) [only for zeroOrMany/oneOrMany relationships]
  • Description: Deletes a specific related entity (e.g. time zone) associated with an entity (e.g. country) by ID.
  • Path Parameters: <key>: ID of the entity. <relatedKey>: ID of the related entity.
  • Response: Returns a status code indicating success or failure.
DELETE /api/<EntityPluralName>/<key>/<RelatedEntityPluralName> (e.g. /api/Countries/1/TimeZones)
  • Description: Deletes all related entities (e.g. time zones) associated with an entity (e.g. country).
  • Path Parameters: <key>: ID of the entity.
  • Response: Returns a status code indicating success or failure.

Related Entities endpoints to manage the relationship between the existing entities

The following endpoints are generated based on relationship => apiGenerateReferenceEndpoint yaml configuration.

GET /api/<EntityPluralName>/<key>/<RelatedEntityPluralName>/$ref (e.g. /api/Countries/1/TimeZones/$ref)
  • Description: Retrieves references to the related entities (e.g. time zones) associated with a specific country.
  • Path Parameters: <key>: ID of the entity.
  • Response: Returns a collection of URIs representing related entities resources.
POST PUT /api/<EntityPluralName>/<key>/<RelatedEntityPluralName>/<relatedKey>/$ref (e.g. /api/Countries/1/TimeZones/1/$ref)
  • Description: Creates a relationship between the existing entity (e.g. country) and the existing related entity (e.g. time zone).
  • Path Parameters: <key>: ID of the entity. <relatedKey>: ID of the related entity.
  • Response: Returns a status code indicating success or failure.
PUT /api/<EntityPluralName>/<key>/<RelatedEntityPluralName>/$ref (e.g. /api/Countries/1/TimeZones/$ref)
  • Description: Creates a relationship between the existing entity (e.g. country) and the existing related entities (e.g. time zones).
  • Path Parameters: <key>: ID of the entity.
  • Request Body: ReferencesDto<relatedKey> (e.g. ReferencesDto<int>) object containing related entities IDs.
  • Response: Returns a status code indicating success or failure.
DELETE /api/<EntityPluralName>/<key>/<RelatedEntityPluralName>/<relatedKey>/$ref (e.g. /api/Countries/1/TimeZones/1/$ref) [only for zeroOrMany/oneOrMany relationships]
  • Description: Deletes the relationship between the entity (e.g. country) and the related entity (e.g. time zone).
  • Path Parameters: <key>: ID of the entity. <relatedKey>: ID of the related entity.
  • Response: Returns a status code indicating success or failure.
DELETE /api/<EntityPluralName>/<key>/<RelatedEntityPluralName>/$ref (e.g. /api/Countries/1/TimeZones/$ref)
  • Description: Deletes all the relationship between the entity (e.g. country) and its the related entities (e.g. time zones).
  • Path Parameters: <key>: ID of the entity.
  • Response: Returns a status code indicating success or failure.

Languages endpoints

GET /api/<EntityPluralName>/<key>/Languages (e.g. /api/Countries/1/Languages)
  • Description: Retrieves a list of all translations for a specific entity (e.g. countries) by ID. OData query is enabled for this endpoint.
  • Path Parameters: <key>: ID of the entity to retrieve translations for.
  • Response: Returns a queryable collection of <Entity>LocalizedDto (e.g. CountryLocalizedDto) objects.
PUT /api/<EntityPluralName>/<key>/Languages/<cultureCode> (e.g. /api/Countries/1/Languages/en-GB)
  • Description: Creates or updates translations for a specific entity (e.g. countries) by ID and for a specific language by CulcutreCode.
  • Path Parameters: <key>: ID of the entity to create/update translations for. <cultureCode>: CultureCode specifying language to create/update translations for.
  • Request Body: <Entity>LocalizedUpsertDto (e.g. CountryLocalizedUpsertDto) object.
  • Response: Returns <Entity>LocalizedDto (e.g. CountryLocalizedDto) object.
DELETE /api/<EntityPluralName>/<key>/Languages/<cultureCode> (e.g. /api/Countries/1/Languages/en-GB)
  • Description: Deletes translations for a specific entity (e.g. countries) by ID and for a specific language by CultureCode.
  • Path Parameters: <key>: ID of the entity to delete translations for. <cultureCode>: CultureCode specifying language to delete translations for.
  • Response: Returns a status code indicating success or failure.
Owned Entities Languages endpoints
GET /api/<EntityPluralName>/<key>/<OwnedEntityName>/Languages (e.g. /api/Countries/1/CountryBarCode/Languages) - for zeroOrOne/exactlyOne relationships only
  • Description: Retrieves translations for a (zero or one/exactly one) owned entity (e.g. CountryBarCode) associated in a to-one relationship with a specific entity (e.g. Country). OData query is enabled for this endpoint.
  • Path Parameters: <key>: ID of the entity.
  • Response: Returns a queryable collection of <OwnedEntityName>LocalizedDto (e.g. CountryBarCodeLocalizedDto) objects.
GET /api/<EntityPluralName>/<key>/<OwnedEntityName>/<relatedKey>/Languages (e.g. /api/Countries/1/CountryLocalNames/1/Languages) - for zeroOrMany/oneOrMany relationships only
  • Description: Retrieves translations for a specific owned entity (e.g. CountryLocalName) associated with a specific entity (e.g. country) by ID. OData query is enabled for this endpoint. OData query is enabled for this endpoint.
  • Path Parameters: <key>: ID of the entity. <relatedKey>: ID of the owned entity.
  • Response: Returns a queryable collection of <OwnedEntityName>LocalizedDto (e.g. CountryLocalNameLocalizedDto) objects.
PUT /api/<EntityPluralName>/<key>/<OwnedEntityName>/Languages/<cultureCode> (e.g. /api/Countries/1/CountryBarCode/Languages/en-GB)
  • Description: Creates or updates translations for a owned entity (e.g. CountryBarCode) associated in a to-one relationship with a specific entity (e.g. Country) and for a specific language.
  • Path Parameters: <key>: ID of the entity. <cultureCode>: CultureCode specifying language to create/update translations for.
  • Request Body: <OwnedEntityName>LocalizedUpsertDto (e.g. CountryBarCodeLocalizedUpsertDto) object.

PUT /api/<EntityPluralName>/<key>/<OwnedEntityPluralName>/<relatedKey>/Languages/<cultureCode> (e.g. /api/Countries/1/CountryLocalNames/1/Languages/en-GB)

  • Description: Creates or updates translations for a specific owned entity (e.g. CountryLocalName) associated in a to-many relationship with a specific entity (e.g. Country) and for a specific language.
  • Path Parameters: <key>: ID of the entity. <relatedKey>: ID of the owned entity to create/update translations for. <cultureCode>: CultureCode specifying language to create/update translations for.
  • Request Body: <OwnedEntityName>LocalizedUpsertDto (e.g. CountryLocalNameLocalizedUpsertDto) object.
DELETE /api/<EntityPluralName>/<key>/<OwnedEntityName>/Languages/<cultureCode> (e.g. /api/Countries/1/CountryBarCode/Languages/en-GB)
  • Description: Deletes translations for a owned entity (e.g. CountryBarCode) associated in a to-one relationship with a specific entity (e.g. Country) and for a specific language.
  • Path Parameters: <key>: ID of the entity. <cultureCode>: CultureCode specifying language to delete translations for.
  • Response: Returns a status code indicating success or failure.
DELETE /api/<EntityPluralName>/<key>/<OwnedEntityPluralName>/<relatedKey>/Languages/<cultureCode> (e.g. /api/Countries/1/CountryLocalNames/1/Languages/en-GB)
  • Description: Deletes translations for a specific owned entity (e.g. CountryLocalName) associated in a to-many relationship with a specific entity (e.g. Country) and for a specific language.
  • Path Parameters: <key>: ID of the entity. <relatedKey>: ID of the owned entity to delete translations for. <cultureCode>: CultureCode specifying language to delete translations for.
  • Response: Returns a status code indicating success or failure.

Enumerations Endpoints

GET /api/<EntityPluralName>/<EnumPluralName> (e.g. /api/Countries/Continents)
  • Description: Retrieves non-conventional values of an enumeration (e.g. Continents) for a specific entity (e.g. country).
  • Response: Returns a queryable collection of <EntityName><EnumName>Dto (e.g. CountryContinentDto) objects.
  • Query Parameters: None
GET /api/<EntityPluralName>/<EnumPluralName>/Languages (e.g. /api/Countries/Continents/Languages)
  • Description: Retrieves localized values of an enumeration (e.g. Continents) for a specific entity (e.g. country).
  • Response: Returns a queryable collection of <EntityName><EnumName>LocalizedDto (e.g. CountryContinentLocalizedDto) objects. OData query is enabled for this endpoint.
  • Query Parameters: None
DELETE /api/<EntityPluralName>/<EntityName><EnumPluralName>/<relatedKey>/Languages<cultureCode> (e.g. /api/Countries/CountryContinents/1/Languages/en-US)
  • Description: Deletes the localized values for a specific enumeration value by ID (e.g. Continents) for a specific culture code in a specific entity (e.g. Country).
  • Path Parameters: <relatedKey>: ID of the enumeration entity to delete translations for. <cultureCode>: CultureCode specifying language to delete translations for.
  • Response: Returns no content.
PUT /api/<EntityPluralName>/<EnumPluralName>/<relatedKey>/Languages/<cultureCode> (e.g. /api/Countries/Continents/1/Languages/en-US)
  • Description: Updates or creates localized value of an enumeration (e.g. Continents) for a specific entity (e.g. country). Requires relatedKey and cultureCode in the URL and a payload with the new value of <EntityName><EnumName>UpsertLocalizedDto (e.g. CountryContinentUpsertLocalizedDto).
  • Path Parameters: <relatedKey>: ID of the enumeration value. <cultureCode>: Culture code of the localized value.
  • Request Body: <EntityName><EnumName>UpsertLocalizedDto (e.g. CountryContinentUpsertLocalizedDto) object.
  • Response: Returns the updated or created <EntityName><EnumName>LocalizedDto (e.g. CountryContinentLocalizedDto) object.
  • Query Parameters: None

Owned Entity Enumerations Endpoints

PUT /api/<EntityPluralName>/<OwnedEntityName>/<EnumPluralName>/<relatedKey>/Languages/<cultureCode> (e.g. /api/Countries/CountryLocalNames/Continents/Languages/en-US)
  • Description: Updates or creates localized value for a specific enumeration value by ID (e.g. Continents) for a specific culture code in an owned entity (e.g. Country Local Name).
  • Path Parameters: <relatedKey>: ID of the enumeration value. <cultureCode>: Culture code of the localized value.
  • Request Body: <OwnedEntityName><EnumName>UpsertLocalizedDto (e.g. CountryLocalNameContinentUpsertLocalizedDto) object.
  • Response: Returns the updated or created <OwnedEntityName><EnumName>LocalizedDto (e.g. CountryLocalNameContinentLocalizedDto) object.
  • Query Parameters: None
DELETE /api/<EntityPluralName>/<EntityName>/<EnumPluralName>/<relatedKey>/Languages/<cultureCode> (e.g. /api/Countries/CountryLocalNames/Continents/1/Languages/en-US)
  • Description: Deletes the localized values for a specific enumeration value by ID (e.g. Continents) for a specific culture code in a specific owned entity (e.g. Country Local Name).
  • Path Parameters: <relatedKey>: ID of the enumeration entity to delete translations for. <cultureCode>: CultureCode specifying language to delete translations for.
  • Response: Returns no content.

nox's People

Contributors

rochar avatar jan-schutte avatar anna-naumova25 avatar ilovemytortoise avatar msadikkoseaupa avatar andresharpe avatar emir-sehovic1 avatar danielhodgegh avatar danield-ap avatar dependabot[bot] avatar dejobratic avatar originalethanhunt avatar fkucuk avatar msadikkose avatar denisvieira-dev avatar becicajla avatar dandandandaann avatar mornevanzyl avatar gjorgji-grgovski-authoritypartners avatar alexandervlasenko avatar andreydegtyarev avatar ggrgovski avatar ahmedtolba1984 avatar

Stargazers

Radoaica Danut Cosmin avatar Geo J Thachankary avatar fred avatar  avatar  avatar  avatar

Watchers

 avatar Robert  avatar  avatar  avatar  avatar

nox's Issues

Create a generator for Domain events

Create concrete classes for all the domain events in a nox solution
yaml definition:

      events:
        - name: CountryNameUpdatedEvent
          description: Raised when the name of a country changes
          type: object
          objectTypeOptions:
            attributes:
              
              - name: CountryId
                description: The identifier of the country. The Iso alpha 2 code
                type: countryCode2
              
              - name: CountryName
                description: The new name of the country
                type: text   

Generated class:

// Generated by DomainEventGenerator::Generate

using Nox.Core.Interfaces.Entity;
using Nox.Types;
using System.Collections.Generic;

namespace SampleService.Domain;

/// <summary>
/// a Domain event which is raised when the name of a country changes
/// </summary>
public partial class CountryNameUpdatedEvent : INoxEvent
{

    /// <summary>
    /// The identity of the country, the Iso Alpha 2 code.
    /// </summary>
    public CountryCode2? CountryId { get; set; } = null!;

    /// <summary>
    /// The new name of the country
    /// </summary>
    public Text? CountryName { get; set; } = null!;
}

Add XtendedAttributes feature

Make it such that Entities can have extended attributes where required.

Automatically track and store value changes in the extended attribute table set

Call for discussing spec...

[Nox.Cli] Include help functionality similar to Powershell get-help or Linux Man pages

In the Templates.Pipeline repository of the Heimdell.Core library we have several yaml templates declared for functions like Docker builds, Helm charts, Builds, deployment etc.

Problem

  • How do I know the template exists?
  • How do I use the template?

Solution

  • Extend Nox.Cli commands to support a helpfile or Man page
  • The cli can then be used to 'discover' what functionality is available and/or supported
  • It can also redirect to a full article on the help site
  • Advanced option would be to 'pull' relevant section straight from Nox support documents referenced by README and noxorg.dev

image

Extended Attributes changes

Extend the XtendedAttributeValue class in Nox.Entity.XtendedAttribues to include

  • DoneAt: DateTimeOffset indicating when a change was made
  • UserIdentifier: string indicating the username or other identifier
  • AppId: smallint indicating the application id that effected the change
  • ClientIp: 16 bytes indicating the IP v4 / V6 address of the origin of the change
  • ClientInfo: serialized string indicating the IPv4, TimeZone, http header info of the client

To facilitate auditing and timestamp entities, another change could be considered where all entity attributes except Id are changed to extended attributes, this will allow for full audit of the entity as each field can have a AsAt dateTimeOffset indicating from when the value becomes effective as well as a record of all previous changes to the field.
This however requires more investigation

Create a new Nox.Lib

Create a new Nox.Lib in the Generators project which includes:

  • the Nox abstractions
  • the generator
  • publish to nuget

Complete sample yaml

  • ammend the sample yaml file to have a proper structure that references the correct internal strutures and uses real world examples of how it would be used in a solution

Lets complete all changes on Nox.Solution as soon as we have a stable solution we can work on this ticket

ETL: Integration pipeline enhancement

Enhance the ETL process to include a concept of handlers.
These handlers will take data from the source and allow the developer to manipulate the incoming data before sending it on to the destination.
Handlers can include functionality like mapping/transformation, validation etc

Nox Listener enhancements

Nox listener projects should be simplified so that:

  • Listeners can easily consume contracts from an api using a dll or perhaps reading metadata from the api endpoint.
  • Listeners should not have to declare a database in yaml config if the yaml definition is used.

Create a generator for data transfer objects

For each dto defined in a nox solution definition in application -> dataTransferObjects a concrete dto class must be created:
definition:
application:
dataTransferObjects:
- name: CountryInfo
description: Dto for country information
attributes:
- name: CountryId
description: The identity of the country, the Iso Alpha 2 code
type: countryCode2

    - name: CountryName
      description: The name of the country
      type: text

generated class:
using Nox.Core.Interfaces.Entity;
using Nox.Types;
using System.Collections.Generic;

namespace SampleService.Application.DataTransferObjects;

///


/// Dto for country information.
///

public partial class CountryInfo : IDynamicDto
{

/// <summary>
/// The identity of the country, the Iso Alpha 2 code.
/// </summary>
public CountryCode2? CountryId { get; set; } = null!;

/// <summary>
/// The name of the country.
/// </summary>
public Text? CountryName { get; set; } = null!;

}

[Nox.Cli] Develop new end-to-end system demo video

** From meeting held 1 June 2023 (00:03:40)

Nox motto: 60 seconds to setup a project and start working, 60 minutes to start testing a microservice.

  • Clean machine
  • Install tool
  • Create folder
  • Run tool
  • Setup simple project
  • Answer questions
  • Slide overlay to document process steps
  • Video should be around 5 minutes and go onto Nox.Cli site
  • Process should adhere to 'deploy under a minute' goal

[OData] Improve Nox.Api error handling & Http response codes

Improve the error handling in Nox.Api oDataController

  • When a duplicate entity will result, return 'Conflict'
  • When an entity is not found, return 'NotFound'
  • When entity sucessfully posted, return 'Created'
  • When an entity is successfully updated, return 'Updated'
  • When an update attempt is made on an entity that has changed, return 'UnprocessableEntity'
  • All other successfull responses must be 'Ok' (200) or 'NoContent' (204)
  • All other errors must return 'BadRequest' (400) with a proper error message

Entity ETag and concurrency

Implement the oData ETag feature in the oData Get, Put & Patch actions.

  • Return the eTag on Get to the client
  • Pass the same ETag back on a PUT or PATCH.
  • On update, if the ETag is outdated return a Conflict (409) response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.