Skip to content

eincioch/SimpleAzureFunction

Repository files navigation

Simple Azure Function - API de Productos

.NET Azure Functions PostgreSQL

API REST serverless construida con Azure Functions v4 y .NET 8 que implementa un CRUD completo para la gestiΓ³n de productos, utilizando Entity Framework Core con PostgreSQL como base de datos.


πŸ“‹ Tabla de Contenidos


πŸ—οΈ Arquitectura

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        Azure Functions Host                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   HTTP       │───▢│   Middleware    │───▢│   Functions    β”‚  β”‚
β”‚  β”‚   Trigger    β”‚    β”‚   (Logging)     β”‚    β”‚   (Endpoints)  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                      β”‚           β”‚
β”‚                                              β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚                                              β”‚  IProductServiceβ”‚  β”‚
β”‚                                              β”‚    (Service)   β”‚  β”‚
β”‚                                              β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                      β”‚           β”‚
β”‚                                              β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚                                              β”‚  DbContext     β”‚  β”‚
β”‚                                              β”‚  (EF Core)     β”‚  β”‚
β”‚                                              β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                      β”‚           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                       β”‚
                                               β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
                                               β”‚   PostgreSQL   β”‚
                                               β”‚   Database     β”‚
                                               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ› οΈ TecnologΓ­as

TecnologΓ­a VersiΓ³n DescripciΓ³n
.NET 8.0 Framework principal
Azure Functions v4 Plataforma serverless
Entity Framework Core 8.0.10 ORM para acceso a datos
PostgreSQL (Npgsql) 8.0.10 Base de datos relacional
Ardalis.Result 10.1.0 PatrΓ³n Result para manejo de respuestas
OpenAPI 1.5.1 DocumentaciΓ³n de API
Application Insights 2.22.0 Monitoreo y telemetrΓ­a

πŸ“ Estructura del Proyecto

FunctionApp/
β”œβ”€β”€ Database/
β”‚   β”œβ”€β”€ Configurations/
β”‚   β”‚   └── ProductConfiguration.cs     # ConfiguraciΓ³n de entidad EF Core
β”‚   β”œβ”€β”€ Constants/
β”‚   β”‚   └── TableNames.cs               # Constantes de nombres de tablas
β”‚   └── ApplicationDbContext.cs         # Contexto de base de datos
β”œβ”€β”€ Entities/
β”‚   └── Product.cs                      # Entidad de dominio
β”œβ”€β”€ Extensions/
β”‚   β”œβ”€β”€ HostExtensions.cs               # Extensiones para migraciones
β”‚   └── HttpRequestExtensions.cs        # Extensiones para HttpRequest
β”œβ”€β”€ Functions/
β”‚   β”œβ”€β”€ CreateProduct.cs                # POST /api/products
β”‚   β”œβ”€β”€ GetAllProducts.cs               # GET /api/products
β”‚   β”œβ”€β”€ GetProductById.cs               # GET /api/products/{id}
β”‚   β”œβ”€β”€ UpdateProduct.cs                # PUT /api/products/{id}
β”‚   └── DeleteProduct.cs                # DELETE /api/products/{id}
β”œβ”€β”€ Middlewares/
β”‚   └── CustomMiddleware.cs             # Middleware de logging
β”œβ”€β”€ Migrations/
β”‚   └── ...                             # Migraciones de EF Core
β”œβ”€β”€ Services/
β”‚   β”œβ”€β”€ Abstraction/
β”‚   β”‚   └── IProductService.cs          # Interfaz del servicio
β”‚   └── ProductService.cs               # ImplementaciΓ³n del servicio
β”œβ”€β”€ Program.cs                          # Punto de entrada
β”œβ”€β”€ host.json                           # ConfiguraciΓ³n del host
└── local.settings.json                 # ConfiguraciΓ³n local

βœ… Prerrequisitos


βš™οΈ ConfiguraciΓ³n

1. Configurar la base de datos

Crea un archivo local.settings.json en la raΓ­z del proyecto FunctionApp:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
    "Postgres": "Host=localhost;Database=ProductsDb;Username=postgres;Password=tu_password"
  }
}

2. Aplicar migraciones

Las migraciones se aplican automΓ‘ticamente al iniciar la aplicaciΓ³n mediante el mΓ©todo ApplyMigrations() en Program.cs.

Para crear nuevas migraciones manualmente:

cd FunctionApp
dotnet ef migrations add NombreMigracion

πŸš€ EjecuciΓ³n Local

Usando Azure Functions Core Tools

cd FunctionApp
func start

Usando Visual Studio

  1. Abrir la soluciΓ³n
  2. Establecer FunctionApp como proyecto de inicio
  3. Presionar F5

Usando Docker

docker build -t simple-azure-function .
docker run -p 7071:80 simple-azure-function

La API estarΓ‘ disponible en: http://localhost:7071/api/


πŸ“‘ Endpoints API

MΓ©todo Ruta DescripciΓ³n Request Body Response
GET /api/products Obtener todos los productos - List<Product>
GET /api/products/{id} Obtener producto por ID - Product o 404
POST /api/products Crear nuevo producto CreateProductRequest Guid
PUT /api/products/{id} Actualizar producto UpdateProductRequest 204 o 404
DELETE /api/products/{id} Eliminar producto - 204 o 404

Modelos de Request

CreateProductRequest

{
  "name": "Producto Ejemplo",
  "description": "DescripciΓ³n del producto",
  "price": 99.99
}

UpdateProductRequest

{
  "description": "Nueva descripciΓ³n",
  "price": 149.99
}

Modelo Product

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "name": "Producto Ejemplo",
  "description": "DescripciΓ³n del producto",
  "price": 99.99
}

πŸ”„ Flujos de la AplicaciΓ³n

Flujo 1: Crear Producto (POST /api/products)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Cliente │────▢│ HTTP Trigger │────▢│ CustomMiddleware│────▢│CreateProduct│────▢│ProductServiceβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                                                                    β”‚                   β”‚
                                                                    β”‚   Create()        β”‚
                                                                    │◀──────────────────│
                                                                    β”‚                   β”‚
                                                              β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                                              β”‚  Return   β”‚       β”‚ DbContext β”‚
                                                              β”‚   Guid    β”‚       β”‚  SaveAsyncβ”‚
                                                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                                                                                        β”‚
                                                                                  β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                                                                  β”‚PostgreSQL β”‚
                                                                                  β”‚  INSERT   β”‚
                                                                                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Pasos detallados:

  1. El cliente envΓ­a una peticiΓ³n POST con el body JSON
  2. El HTTP Trigger activa la funciΓ³n CreateProduct
  3. El CustomMiddleware registra la entrada en logs
  4. Se deserializa el request usando HttpRequestExtensions.GetBody<T>()
  5. Se llama a IProductService.Create() con los datos
  6. ProductService crea una nueva entidad Product
  7. EF Core persiste el producto en PostgreSQL
  8. Se retorna el GUID del producto creado

Flujo 2: Obtener Todos los Productos (GET /api/products)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Cliente │────▢│ HTTP Trigger │────▢│ CustomMiddleware│────▢│GetAllProducts β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                                                                     β”‚
                                                               β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                                               β”‚ProductServiceβ”‚
                                                               β”‚  GetAll() β”‚
                                                               β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                                                                     β”‚
                                                               β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                                               β”‚ DbContext β”‚
                                                               β”‚ToListAsyncβ”‚
                                                               β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                                                                     β”‚
                                                               β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                                               β”‚PostgreSQL β”‚
                                                               β”‚  SELECT * β”‚
                                                               β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                                                                     β”‚
                                                               β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                                               β”‚Return JSONβ”‚
                                                               β”‚List<Product>β”‚
                                                               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Pasos detallados:

  1. El cliente envΓ­a una peticiΓ³n GET
  2. Se ejecuta el middleware de logging
  3. ProductService.GetAll() ejecuta una consulta a la base de datos
  4. EF Core traduce la consulta a SQL SELECT
  5. Se retorna la lista de productos como JSON

Flujo 3: Obtener Producto por ID (GET /api/products/{id})

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Cliente │────▢│ HTTP Trigger │────▢│GetProductById │────▢│ProductServiceβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                                                                   β”‚
                                                             β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                                             β”‚ GetById() β”‚
                                                             β”‚Result<T>  β”‚
                                                             β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                                                                   β”‚
                                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                              β”‚                    β”‚                    β”‚
                                        β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                        β”‚  Existe   β”‚        β”‚  Producto β”‚        β”‚No Existe β”‚
                                        β”‚   βœ“       β”‚        β”‚   Found   β”‚        β”‚   βœ—      β”‚
                                        β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                                              β”‚                                         β”‚
                                        β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”                             β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                        β”‚ Return    β”‚                             β”‚ Return    β”‚
                                        β”‚ 200 + JSONβ”‚                             β”‚ 404       β”‚
                                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Pasos detallados:

  1. El cliente envΓ­a GET con el GUID en la ruta
  2. ProductService.GetById() busca el producto
  3. Se usa el patrΓ³n Result<T> de Ardalis.Result
  4. Si existe β†’ retorna 200 OK con el producto
  5. Si no existe β†’ retorna 404 Not Found

Flujo 4: Actualizar Producto (PUT /api/products/{id})

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Cliente │────▢│ HTTP Trigger │────▢│UpdateProduct│────▢│ProductServiceβ”‚
β”‚  PUT     β”‚     β”‚              β”‚     β”‚             β”‚     β”‚  Update()   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                                                                 β”‚
                                                           β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                                           β”‚Find Productβ”‚
                                                           β”‚by ID       β”‚
                                                           β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                                                                 β”‚
                                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                          β”‚                      β”‚                      β”‚
                                    β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                    β”‚  Existe   β”‚          β”‚  Update   β”‚          β”‚No Existe β”‚
                                    β”‚   βœ“       │─────────▢│Entity     β”‚          β”‚   βœ—      β”‚
                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                                                                 β”‚                      β”‚
                                                           β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                                           β”‚SaveChangesβ”‚          β”‚ Return    β”‚
                                                           β”‚Return 204 β”‚          β”‚ 404       β”‚
                                                           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Pasos detallados:

  1. El cliente envΓ­a PUT con ID en ruta y datos en body
  2. Se deserializa UpdateProductRequest
  3. ProductService.Update() busca el producto
  4. Si existe β†’ actualiza Description y Price
  5. EF Core persiste los cambios
  6. Retorna 204 No Content o 404 Not Found

Flujo 5: Eliminar Producto (DELETE /api/products/{id})

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Cliente │────▢│ HTTP Trigger │────▢│DeleteProduct│────▢│ProductServiceβ”‚
β”‚  DELETE  β”‚     β”‚              β”‚     β”‚             β”‚     β”‚  Delete()   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                                                                 β”‚
                                                           β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                                           β”‚Find Productβ”‚
                                                           β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                                                                 β”‚
                                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                          β”‚                      β”‚                      β”‚
                                    β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                    β”‚  Existe   β”‚          β”‚  Remove   β”‚          β”‚No Existe β”‚
                                    β”‚   βœ“       │─────────▢│  Entity   β”‚          β”‚   βœ—      β”‚
                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                                                                 β”‚                      β”‚
                                                           β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                                                           β”‚SaveChangesβ”‚          β”‚ Return    β”‚
                                                           β”‚Return 204 β”‚          β”‚ 404       β”‚
                                                           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Flujo de InicializaciΓ³n de la AplicaciΓ³n

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           Program.cs - Startup                               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                              β”‚
β”‚  1. HostBuilder                                                              β”‚
β”‚     β”‚                                                                        β”‚
β”‚     β”œβ”€β”€β–Ά ConfigureFunctionsWebApplication()                                  β”‚
β”‚     β”‚    └──▢ UseMiddleware<CustomMiddleware>()                              β”‚
β”‚     β”‚                                                                        β”‚
β”‚     β”œβ”€β”€β–Ά ConfigureServices()                                                 β”‚
β”‚     β”‚    β”œβ”€β”€β–Ά AddDbContext<ApplicationDbContext>()                           β”‚
β”‚     β”‚    β”‚    └──▢ UseNpgsql(connectionString)                               β”‚
β”‚     β”‚    β”‚                                                                   β”‚
β”‚     β”‚    └──▢ AddScoped<IProductService, ProductService>()                   β”‚
β”‚     β”‚                                                                        β”‚
β”‚     └──▢ ConfigureOpenApi()                                                  β”‚
β”‚                                                                              β”‚
β”‚  2. Build()                                                                  β”‚
β”‚     β”‚                                                                        β”‚
β”‚     └──▢ host.ApplyMigrations()                                              β”‚
β”‚          └──▢ Database.Migrate()                                             β”‚
β”‚                                                                              β”‚
β”‚  3. Run()                                                                    β”‚
β”‚     └──▢ AplicaciΓ³n lista para recibir requests                              β”‚
β”‚                                                                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“– DocumentaciΓ³n OpenAPI

La API incluye documentaciΓ³n OpenAPI/Swagger automΓ‘tica. DespuΓ©s de iniciar la aplicaciΓ³n, accede a:

  • Swagger UI: http://localhost:7071/api/swagger/ui
  • OpenAPI JSON: http://localhost:7071/api/openapi/v3.json

Cada endpoint estΓ‘ documentado con:

  • OperaciΓ³n y tags
  • ParΓ‘metros de ruta
  • Request body schemas
  • Response schemas y cΓ³digos de estado

🐳 Docker

El proyecto estΓ‘ configurado para ejecutarse en contenedores Docker con soporte para Linux.

Dockerfile

El proyecto incluye configuraciΓ³n para Docker con:

  • Target OS: Linux
  • Mount directory: /home/site/wwwroot

Variables de entorno necesarias

Postgres=Host=db;Database=ProductsDb;Username=postgres;Password=password
AzureWebJobsStorage=UseDevelopmentStorage=true
FUNCTIONS_WORKER_RUNTIME=dotnet-isolated

πŸ“ Licencia

Este proyecto estΓ‘ bajo la licencia MIT.


πŸ‘€ Autor

eincioch

Repositorio: SimpleAzureFunction

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors