API con ASP.NET MVC 6 y SQL Server mediante Entity Framework core 6 - Code First - Parte 2
Published: 2022-06-24 05:01:59

En la **[Primera parte](https://dev.to/veronicaguamann/api-con-aspnet-mvc-6-y-sql-server-mediante-entity-framework-core-6-code-first-parte-1-2i05)** vimos la configuración de Entity Framework en nuestro proyecto, para poder conectarnos con SQL Server. Si ya tienes todo listo podemos continuar, si aún no la tienes puedes volver [AQUÍ](https://dev.to/veronicaguamann/api-con-aspnet-mvc-6-y-sql-server-mediante-entity-framework-core-6-code-first-parte-1-2i05).

En esta segunda parte vamos a realizar los Métodos CRUD de nuestra API, En este caso vamos a trabajar con un repositorio, interfaz, controlador y finalmente probarlo mediante Swagger. Si bien podríamos hacerlo directamente en el controlador, no es recomendable tener los métodos tan expuestos. y en proyectos reales, lo realizamos en proyectos diferentes (Data, Services, API), en este tutorial lo simularemos en un solo proyecto.

Dicho esto, vamos a ello.

##1. Crear la interfaz
Para esto, en nuestra carpeta Models vamos a crear una nueva carpeta llamada _Repository_, dentro de esta agregamos una interfaz que se llamará _IProductRepository_. 
Aquí vamos a agregar los métodos que tendrá nuestro CRUD.
```csharp
namespace DemoAPI.Models.Repository
{
    public interface IProductRepository
    {
        Task<Product> CreateProductAsync(Product product);
        Task<bool> DeleteProductAsync(Product product);
        Product GetProductById(int id);
        IEnumerable<Product> GetProducts();
        Task<bool> UpdateProductAsync(Product product);
    }
}
```
##2. Crear el Repositorio
En la misma carpeta, _Repository_ agregaremos una nueva clase y la llamaremos ProductRepository.
El siguiente paso será realizar la implementación de nuestra interfaz _IProductRepository_.  Aquí vamos a realizar nuestro CRUD. En este archivo vamos a realizar la conexión a nuestra base de datos, así no lo tenemos expuesto directamente en nuestro controlador y se verá de la siguiente manera.

```csharp
using Microsoft.EntityFrameworkCore;

namespace DemoAPI.Models.Repository
{
    public class ProductRepository : IProductRepository
    {
        protected readonly DemoContext _context;
        public ProductRepository(DemoContext context) => _context = context;

        public IEnumerable<Product> GetProducts()
        {
            return _context.Products.ToList();
        }

        public Product GetProductById(int id)
        {
            return _context.Products.Find(id);
        }
        public async Task<Product> CreateProductAsync(Product product)
        {
            await _context.Set<Product>().AddAsync(product);
            await _context.SaveChangesAsync();
            return product;
        }

        public async Task<bool> UpdateProductAsync(Product product)
        {
            _context.Entry(product).State = EntityState.Modified;
            await _context.SaveChangesAsync();
            return true;
        }

        public async Task<bool> DeleteProductAsync(Product product)
        {
            //var entity = await GetByIdAsync(id);
            if (product is null)
            {
                return false;
            }
            _context.Set<Product>().Remove(product);
            await _context.SaveChangesAsync();

            return true;
        }
    }
}
```

##3. Configurar Repository
Para poder usar nuestra interfaz tenemos que realizar la siguiente **configuración** en el archivo _Program.cs_, vamos a agregar las siguientes líneas debajo de la configuración de Entity Framework.
```csharp
builder.Services.AddTransient<IProductRepository, ProductRepository>();
```

##4. Configurar el controlador
Ya tenemos todo listo para crear nuestro controlador.
En la Carpeta _Controlador_ agregamos un nuevo controlador y lo llamaremos _ProductController_.
Vamos a crear la configuración para poder acceder desde la interfaz al repositorio y poder hacer la llamada a los métodos creados en esta clase.
```csharp
private IProductRepository _productRepository;

        public ProductController(IProductRepository productRepository)
        {
            _productRepository = productRepository;
        }
```

##5. Crear los métodos en nuestro controlador
Como se trata de un API, mediante los _verbos Http_ vamos a etiquetar cada método acorde a la acción que va a realizar, HttpGet para obtener Datos, HttpPost para hacer inserts, HttpPut para Editar datos existentes, y HttpDelete para eliminar.
Para crear los métodos de nuestro CRUD, mediante la interfaz llamamos a los métodos ya creados en el repositorio y enviamos los datos recibidos y nuestro controlador quedará de la siguiente forma.
```csharp
using DemoAPI.Models;
using DemoAPI.Models.Repository;
using Microsoft.AspNetCore.Mvc;

namespace DemoAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductController : ControllerBase
    {
        private IProductRepository _productRepository;

        public ProductController(IProductRepository productRepository)
        {
            _productRepository = productRepository;
        }

        [HttpGet]
        [ActionName(nameof(GetProductsAsync))]
        public IEnumerable<Product> GetProductsAsync()
        {
            return _productRepository.GetProducts();
        }

        [HttpGet("{id}")]
        [ActionName(nameof(GetProductById))]
        public ActionResult<Product> GetProductById(int id)
        {
            var productByID = _productRepository.GetProductById(id);
            if (productByID == null)
            {
                return NotFound();
            }
            return productByID;
        }

        [HttpPost]
        [ActionName(nameof(CreateProductAsync))]
        public async Task<ActionResult<Product>> CreateProductAsync(Product product)
        {
            await _productRepository.CreateProductAsync(product);
            return CreatedAtAction(nameof(GetProductById), new { id = product.Id }, product);
        }

        [HttpPut("{id}")]
        [ActionName(nameof(UpdateProduct))]
        public async Task<ActionResult> UpdateProduct(int id, Product product)
        {
            if (id != product.Id)
            {
                return BadRequest();
            }

            await _productRepository.UpdateProductAsync(product);

            return NoContent();

        }

        [HttpDelete("{id}")]
        [ActionName(nameof(DeleteProduct))]
        public async Task<IActionResult> DeleteProduct(int id)
        {
            var product = _productRepository.GetProductById(id);
            if (product == null)
            {
                return NotFound();
            }

            await _productRepository.DeleteProductAsync(product);

            return NoContent();
        }
    }
}
```
Finalmente vamos a **ejecutar nuestra Aplicación** y vamos a _probar que todo funcione_ correctamente.
Por defecto al crearse el proyecto, nuestra API viene integrada con _Swagger_, que es una OPEN API para documentación y viene integrada con una interfaz que nos permite probar nuestros métodos. (Si deseas saber más de Swagger te dejo el siguiente [artículo](https://dev.to/veronicaguamann/sesion-apis-con-net-5-y-documentacion-con-swagger-3gk))

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l0xequnqih6tq75nrtrp.jpg)

Primero vamos a probar nuestro método Post, ingresando un producto, en este caso simularemos el ingreso de un teclado.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uxayu645q5l9sewbenyi.jpg)

Al darle a **Execute** tiene que darnos una respuesta, en este caso el código 200 para indicarnos que todo está correcto.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ktbue7w9s2yxhgnz5enh.jpg)

Finalmente vamos a probar nuestro Get y verificar que nuestro insertar funciono correctamente.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eynuwch2ba0xqqh99qub.jpg)
Y así hemos completado nuestra API.

Muchas gracias por leerme y Nos vemos en [Twitter](https://twitter.com/veronicaguamann) e [Instagram](https://www.instagram.com/veronicaguamann) ;)