Skip to content

Repository files navigation

VPSDemo

The goal of the test task is to develop a web API of a task planning system. The web API must allow to create and edit a task hierarchy, as well as perform calculations on the data fields of the tasks in the hierarchy.

Technologies used:

ASP.NET Core 6, C#, EntityFramework Core, MS SQL Server Database, Docker

App architecture used with different layers

promisechains

  • VPSDemo.Api (main Web API project) contains Controllers (endpoints), Contracts, Mappers, Filters.
  • VPSDemo.Application contains Interfaces, Errors, Logic to fetch data
  • VPSDemo.Domain contains Entities
  • VPSDemo.Infrastructure contains Repositories, Migration files and other fiels related to DB

Libraries and patterns:

Clean Architectue, Domain Driven Design, Repository Pattern

  • Automapper is set in VPSDemo.Api.Mapper
  • TaskMapperProfiles.cs to configure automapper for Task entity
  • Instead of throwing and using exceptions we use a Return object.
  • Return object has a Value, IsFailed, IsSuccess properties.
  • errors of Return object are handled via ProblemHandler in BaseController.

Error and Validations Handling

  • Globar errors are handled in VPSDemo.Api.Controllers ErrorsController.cs
  • All other non server side errors are handled via ProblemHandler method in VPSDemo.Api.Controllers BaseController.cs
  • Uri and query identifier parameter is validated via ValidateIdentifier method in VPSDemo.Api.Validations BaseValidation.cs
  • UI Models (Contracts)are validated via validation filter defined in VPSDemo.Api.Filters ValidationFilterAttribute.cs
  • All errors are serverd to the user with ProblemDetails class Problem Details Specification for HTTP APIs
  • in order to add custom 'errorMessage' to ProblemDetails class we override method CreateProblemDetails in VPSDemo.Api.Common VPSProblemDetailsFactory.cs

DB and UI models

  • DB Model (Entity) defined in VPSDemo.Domain.Entities Task.cs class
  • UI models (Contracts) defined in VPSDemo.Api.Contracts

Capabilities of the Web API

  1. Create Task, Delete Task, Edit Task, Get Task, Assign Sub task
  2. Get Task - also retrieves sub Tasks
  3. Delete Task - Only a task which does not have sub-tasks can be deleted.

Web API Endpoints & Examples

promisechains

Create

POST VPSDemo_URL/tasks

Request body Response (SUCCESS 200 Ok)
{
    "title": "MAIN TASK A",
    "description": "description",
    "effortEstimation": 1
}
{
    "identifier": 1,
    "title": "MAIN TASK A",
    "description": "description",
    "effortEstimation": 1,
    "aggregatedEffortEstimation": 281,
    "status": "New",
    "subTasks": [],
    "creationDate": "2022-11-13T23:15:12"
}
Request body Response (FAIL 400)
{ 
  "description": "description"
}
{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "Validation Error",
    "status": 400,
    "traceId": "00-21790aa1386552307b4397420650fefa-18df5db6c8db92e1-00",
    "errorMessage": [
        "The Title field is required."
    ]
}

Edit

PUT VPSDemo_URL/tasks/2

Request body Response (FAIL 400)
{ 
  "description": "description"
}
{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "Validation Error",
    "status": 400,
    "traceId": "00-21790aa1386552307b4397420650fefa-18df5db6c8db92e1-00",
    "errorMessage": [
        "The Status field is required.",
        "The field Status is invalid"
    ]
}

Assign sub task

PUT VPSDemo_URL/tasks/assignSubTask/4?parentIdentifier=3

Query (Key: Value) Response (Success 200 Ok)
  parentIdentifier: 3
{
  "identifier": 3,
  "title": "TASK B",
  "description": "description",
  "effortEstimation": 0,
  "aggregatedEffortEstimation": 80,
  "status": "New",
  "subTasks": [
    {
      "identifier": 4,
      "title": "TASK C",
      "description": "description",
      "effortEstimation": 80,
      "aggregatedEffortEstimation": 0,
      "status": "New",
      "subTasks": [],
      "creationDate": "2022-11-13T23:17:44"
    }
  ],
  "creationDate": "2022-11-13T23:15:12"
}

Fetch

Get VPSDemo_URL/tasks/3

Response (Success 200 Ok)
{
  "identifier": 3,
  "title": "TASK B",
  "description": "description",
  "effortEstimation": 0,
  "aggregatedEffortEstimation": 80,
  "status": "New",
  "subTasks": [
    {
      "identifier": 4,
      "title": "TASK C",
      "description": "description",
      "effortEstimation": 80,
      "aggregatedEffortEstimation": 0,
      "status": "New",
      "subTasks": [],
      "creationDate": "2022-11-13T23:17:44"
    }
  ],
  "creationDate": "2022-11-13T23:15:12"
}

Delete

Delete VPSDemo_URL/tasks/3

Response (Success 204 NoContent)

Delete VPSDemo_URL/tasks/1

Response (FAIL 409)
{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.8",
    "title": "Conflict",
    "status": 409,
    "traceId": "00-7d2127bfe809238b8d944c0cb64fec29-d17390d3fe719a93-00",
    "errorMessage": [
        "Task with identifier [1] has assigned one or more Task with identifiers: [4]"
    ]
}

Docker

VPSDemo.Api contains Dockerfile to build docker image.
We use base image mcr.microsoft.com/dotnet/sdk:6.0 to build binaries.
.Net runtime image mcr.microsoft.com/dotnet/aspnet:6.0 is used to serve artefacts we've created

Local docker container running our image:

promisechains

Opening the browser to display app runnig from docker container:

promisechains

About

VPSDemo: A task planning web API built with ASP.NET Core 6, employing Clean Architecture and EntityFramework Core, featuring automated mapping with AutoMapper and error handling with FluentResults.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages