En la Primera parte 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Í.
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.
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.
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.
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.
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.
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)
Primero vamos a probar nuestro método Post, ingresando un producto, en este caso simularemos el ingreso de un teclado.
Al darle a Execute tiene que darnos una respuesta, en este caso el código 200 para indicarnos que todo está correcto.
Finalmente vamos a probar nuestro Get y verificar que nuestro insertar funciono correctamente.
Y así hemos completado nuestra API.
Muchas gracias por leerme y Nos vemos en Twitter e Instagram ;)
Top comments (5)
Hola. Sigo tus indicaciones, y al ejecutar el HttpPost tira un error. Se debe a que la columna Id en la tabla Product es autoincrementable. Si a ese campo de la tabla le saco el autoincremento funciona, pero la idea es que la base de datos gestione la clave primaria. Como puedo solucionarlo?
Saludos
Hugo Fajardo
Hola Hugo muchas gracias por seguir el tutorial.
Nose si entiendo bien, pero ¿deseas que el ID sea auto incrementable?
Si, eso quiero.
En teoría con la etiqueta [Key] en el atributo del ID debería funcionar pero podemos ayudarnos de la etiqueta
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] debajo de [Key] y arriba del atributo.
Puedes probarle eso porfis y me comentas
Hola, llegué aqui buscando informacion sobre EF en NetCore6 y con MVC. Recien estoy empezando en programacion este año, leyendo libros y precticando, y en el curso actual que llevo de VS solo enseñan EF pero con NetFramework(Solo Windows).
Me alegró al inicio encontrar info en Español para NetCore6, pero el codigo es dificil de entender sin ningun comentario que lo acompañe. Y simplemente copiar y pegar sin entenderlo no creo que sea de provecho.
Lo envio como critica constructiva, ya que por alguna razon los expertos de habla inglesa mayormente entregan informacion más detallada y digerible en sus posts o en youtube o en sus respuestas en stackoverflow, a diferencia de los de idioma español que se limitan en explicaciones o en detalles.
Pienso que seria bueno que algun dia se pueda cambiar eso.