diff --git a/src/Belezanaweb.API/Belezanaweb.API.csproj b/src/Belezanaweb.API/Belezanaweb.API.csproj
new file mode 100644
index 0000000..2a98b58
--- /dev/null
+++ b/src/Belezanaweb.API/Belezanaweb.API.csproj
@@ -0,0 +1,17 @@
+
+
+
+ netcoreapp3.1
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Belezanaweb.API/Controllers/ProductController.cs b/src/Belezanaweb.API/Controllers/ProductController.cs
new file mode 100644
index 0000000..61a04c4
--- /dev/null
+++ b/src/Belezanaweb.API/Controllers/ProductController.cs
@@ -0,0 +1,45 @@
+using Belezanaweb.Application.Core.Commands;
+using Belezanaweb.Application.Products.Commands;
+using Belezanaweb.Application.Products.Queries;
+using Belezanaweb.Application.Products.ViewModels;
+using MediatR;
+using Microsoft.AspNetCore.Mvc;
+using System.Threading.Tasks;
+
+namespace Belezanaweb.API.Controllers
+{
+ [Route("api/[controller]")]
+ public class ProductController : ControllerBase
+ {
+ private readonly IMediator _mediator;
+
+ public ProductController(IMediator mediator)
+ {
+ _mediator = mediator;
+ }
+
+ [HttpGet("{sku:long}")]
+ public async Task> GetProductBySkuAsync([FromRoute] long sku)
+ {
+ return await _mediator.Send(new GetProductBySkuQuery(sku));
+ }
+
+ [HttpPost]
+ public async Task CreateProductAsync([FromBody] CreateProductCommand command)
+ {
+ return await _mediator.Send(command);
+ }
+
+ [HttpPut]
+ public async Task AlterProductAsync([FromBody] AlterProductCommand command)
+ {
+ return await _mediator.Send(command);
+ }
+
+ [HttpDelete("{sku:long}")]
+ public async Task DeleteProductAsync([FromRoute] long sku)
+ {
+ return await _mediator.Send(new DeleteProductCommand(sku));
+ }
+ }
+}
diff --git a/src/Belezanaweb.API/Program.cs b/src/Belezanaweb.API/Program.cs
new file mode 100644
index 0000000..f3df621
--- /dev/null
+++ b/src/Belezanaweb.API/Program.cs
@@ -0,0 +1,20 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Hosting;
+
+namespace Belezanaweb.API
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ CreateHostBuilder(args).Build().Run();
+ }
+
+ public static IHostBuilder CreateHostBuilder(string[] args) =>
+ Host.CreateDefaultBuilder(args)
+ .ConfigureWebHostDefaults(webBuilder =>
+ {
+ webBuilder.UseStartup();
+ });
+ }
+}
diff --git a/src/Belezanaweb.API/Startup.cs b/src/Belezanaweb.API/Startup.cs
new file mode 100644
index 0000000..12cf21c
--- /dev/null
+++ b/src/Belezanaweb.API/Startup.cs
@@ -0,0 +1,56 @@
+using Belezanaweb.Application.Core.Middlewares;
+using Belezanaweb.Infra.IoC;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.HttpsPolicy;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+
+namespace Belezanaweb.API
+{
+ public class Startup
+ {
+ public Startup(IConfiguration configuration)
+ {
+ Configuration = configuration;
+ }
+
+ public IConfiguration Configuration { get; }
+
+ // This method gets called by the runtime. Use this method to add services to the container.
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddControllers();
+ IoC.Load(services);
+ }
+
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+ {
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ }
+ app.UseGlobalExceptionHandlerMiddleware();
+
+ app.UseHttpsRedirection();
+
+ app.UseRouting();
+
+ app.UseAuthorization();
+
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapControllers();
+ });
+ }
+ }
+}
diff --git a/src/Belezanaweb.API/appsettings.Development.json b/src/Belezanaweb.API/appsettings.Development.json
new file mode 100644
index 0000000..8983e0f
--- /dev/null
+++ b/src/Belezanaweb.API/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ }
+}
diff --git a/src/Belezanaweb.API/appsettings.json b/src/Belezanaweb.API/appsettings.json
new file mode 100644
index 0000000..d9d9a9b
--- /dev/null
+++ b/src/Belezanaweb.API/appsettings.json
@@ -0,0 +1,10 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/src/Belezanaweb.Application.Core/Belezanaweb.Application.Core.csproj b/src/Belezanaweb.Application.Core/Belezanaweb.Application.Core.csproj
new file mode 100644
index 0000000..0acc881
--- /dev/null
+++ b/src/Belezanaweb.Application.Core/Belezanaweb.Application.Core.csproj
@@ -0,0 +1,19 @@
+
+
+
+ netcoreapp3.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Belezanaweb.Application.Core/Commands/IRequestBase.cs b/src/Belezanaweb.Application.Core/Commands/IRequestBase.cs
new file mode 100644
index 0000000..0fe98f7
--- /dev/null
+++ b/src/Belezanaweb.Application.Core/Commands/IRequestBase.cs
@@ -0,0 +1,9 @@
+using FluentValidation.Results;
+
+namespace Belezanaweb.Application.Core.Commands
+{
+ public interface IRequestBase
+ {
+ ValidationResult ValidationResult { get; }
+ }
+}
diff --git a/src/Belezanaweb.Application.Core/Commands/RequestBase.cs b/src/Belezanaweb.Application.Core/Commands/RequestBase.cs
new file mode 100644
index 0000000..e14ac8a
--- /dev/null
+++ b/src/Belezanaweb.Application.Core/Commands/RequestBase.cs
@@ -0,0 +1,13 @@
+using FluentValidation.Results;
+using MediatR;
+using System.Text.Json.Serialization;
+
+namespace Belezanaweb.Application.Core.Commands
+{
+ public abstract class RequestBase : IRequestBase, IRequest
+ {
+ [JsonIgnore]
+ public ValidationResult ValidationResult { get; set; }
+ public abstract bool IsValid();
+ }
+}
diff --git a/src/Belezanaweb.Application.Core/Commands/Response.cs b/src/Belezanaweb.Application.Core/Commands/Response.cs
new file mode 100644
index 0000000..a413284
--- /dev/null
+++ b/src/Belezanaweb.Application.Core/Commands/Response.cs
@@ -0,0 +1,50 @@
+using Newtonsoft.Json;
+
+namespace Belezanaweb.Application.Core.Commands
+{
+ public class BaseResponse where TRequest : class
+ {
+ [JsonProperty("success")]
+ public bool Success { get; set; }
+ [JsonProperty("errorMessages")]
+ public string[] ErrorMessages { get; set; }
+ [JsonProperty("data")]
+ public TRequest Data { get; set; }
+ }
+
+ public class Response : BaseResponse where TRequest : class
+ {
+ public Response(string errorMessage)
+ {
+ base.ErrorMessages = new[] { errorMessage } ;
+ Success = false;
+ Data = default;
+ }
+
+ public Response(TRequest data)
+ {
+ Data = data;
+ Success = true;
+ }
+ }
+
+ public class Response : BaseResponse