Jorge Serrano
  • Home

JSON Patch en ASP.NET Core 5 Web API

  • By jorge
  • Dic-23-2020
  • .NET 5, ASP.NET Core 5, C#, JSON
  • 0 Comments.

Introducción

Los verbos más habituales a la hora de trabajar con una Web API suelen ser GET, PUT y POST.

Y en menor medida PATCH y DELETE.

PUT y PATCH se utilizan para actualizar recursos existentes, pero la diferencia entre PUT y PATCH, es que PUT actualiza, o mejor dicho reemplaza, un recurso existente, mientras que PATCH, especifica únicamente los cambios.

HTTP VERBS ACTION
DELETE Delete
GET Read
POST Create
PUT Update
PATCH

 

JSON Patch

De acuerdo a lo anterior, ya tenemos claro que PUT y PATCH no es exactamente lo mismo, pero… ¿y qué es JSON Patch?.

JSON Patch es un formato para especificar actualizaciones que serán aplicadas a un recurso.

La especificación RFC-6902 nos especifica al detalle JSON Patch.

En rasgos generales, un JSON Patch es un documento, con un array o matriz de operaciones.

Un ejemplo de JSON Patch sería:

[
    {"op" : "replace", "path" : "/Name", "value" : "George"}
]

Se pueden anidar operaciones diferentes, pero cada operación identifica un cambio concreto.

 

Formato de un JSON Patch

De acuerdo al ejemplo de JSON Patch anterior, tenemos que tener en cuenta que un JSON Patch estará formado por tantas operaciones atómicas o individuales como consideremos, y que el formato de un JSON Patch está formado por las siguientes partes generales:

op
Para indicar el tipo de operación.

Las posibles operaciones son:

  • add
  • copy
  • move
  • remove
  • replace
  • test

path
Para indicar el elemento a actualizar.
Si nuestro objeto tiene niveles, dividiremos esos niveles con el carácter /
Imaginemos que tenemos una clase Person, que dentro de ésta tiene una clase Address, y esa clase una propiedad Street.
El path en este caso será algo similar a /address/street

value
Para indicar el nuevo valor del elemento a actualizar.

 

JSON Patch en ASP.NET Core 5

Y una vez llegados a este punto, vamos a mostrar cómo utilizar JSON Path en una Web API de ASP.NET Core 5 (aunque también lo podemos hacer en otras versiones de .NET Core).

He creado un proyecto de tipo Web Api.

Dentro de él, lo primero que debemos tener en cuenta es que necesitaremos un paquete NuGet.

  • Microsoft.AspNetCore.Mvc.NewtonsoftJson

Así que lo agregaremos al proyecto.

Una aclaración en este punto. Existe un paquete NuGet que deberíamos añadir y utilizar, y que se llama Microsoft.AspNetCore.JsonPatch, sin embargo, cabe destacar que en este ejemplo voy a utilizar Microsoft.AspNetCore.Mvc.NewtonsoftJson que hace referencia a Microsoft.AspNetCore.JsonPatch, motivo por el cuál, no necesito agregar dicho paquete NuGet al proyecto.

Una vez hecho esto, he creado una carpeta Models dentro de la cuál he creado una clase Person con el siguiente código:

public class Person
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

Por otro lado, he creado una carpeta Services con una interfaz de nombre IDataService y una clase de nombre DataService, cuyo código es el siguiente:

public interface IDataService
{
    Guid Add(Person person);
    Person GetBy(Guid id);
    List<Person> GetPeople();
}

y

public class DataService : IDataService
{
    private List<Person> _people = new List<Person>();

    public Guid Add(Person person)
    {
        person.Id = Guid.NewGuid();
        _people.Add(person);
        return person.Id;
    }

    public Person GetBy(Guid id) => _people.Where(x => x.Id == id).FirstOrDefault();

    public List<Person> GetPeople() => _people;
}

Una vez hecho esto, iremos a la clase Startup y nos situaremos en el método ConfigureSerrvices, dejándolo de esta forma:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
            .AddNewtonsoftJson();

    services.AddSingleton<IDataService, DataService>();
}

Ahora que ya tenemos preparada la parte central de toda nuestra Web API, vamos a trabajar en los controladores.

En nuestro caso, he creado un controlador de nombre EmployeeController.

Dentro de este controlador he añadido cuatro operaciones. Las cuatro operaciones que tengo en el servicio.

Dos de esas operaciones son operaciones GET.

Otra de ellas es una operación POST para insertar datos.

Y la última es una operación PATCH, que es precisamente lo que trato de explicar en esta entrada.

El constructor del controlador, resuelve la dependencia de IDataService. Y las operaciones se ejecutan a través de este servicio.

El código completo de nuestro controlador queda de la siguiente forma:

[ApiController]
[Route("api/[controller]")]
public class EmployeeController : ControllerBase
{
    private readonly IDataService _dataService;

    public EmployeeController(IDataService dataService)
    {
        _dataService = dataService;
    }

    [HttpGet]
    public IActionResult Get() => Ok(_dataService.GetPeople());

    [HttpGet("{id}")]
    public IActionResult GetBy(Guid id) => Ok(_dataService.GetBy(id));

    [HttpPatch("update/{id}")]
    public IActionResult Patch(Guid id, [FromBody] JsonPatchDocument<Person> personPatch)
    {
        if (personPatch != null)
        {
            var person = _dataService.GetBy(id);

            if (person != null)
            {
                personPatch.ApplyTo(person);
                return Ok(person);
            }
        }

        return BadRequest();
    }

    [HttpPost]
    public IActionResult Add(Person person) => Ok(_dataService.Add(person));
}

Desde Postman u otro programa, podemos hacer peticiones a nuestra Web API para jugar con ella.

Al principio no tiene datos, por lo que realizando una llamada a la operación POST, deberíamos recibir información sobre la operación como por ejemplo:

Si ejecutamos las operaciones GET, tanto para obtener todos los empleados, como para obtener que el que acabamos de crear, obtendremos sus datos.

Por ejemplo, la operación GET para obtener el empleado recién creado, quedaría de esta forma:

Y por último, la operación PATCH en la que realizaremos dos modificaciones sobre el elemento creado, implica dos operaciones.

Una por cada modificación.

En nuestro caso, modificaremos el nombre y la edad del empleado, así que nuestro JSON tendrá un aspecto similar al siguiente:

[
    {"op" : "replace", "path" : "/Name", "value" : "Frank"},
    {"op" : "replace", "path" : "/Age", "value" : "37"}
]

Un array o matriz de operaciones.

Dentro de Postman, tendrá un aspecto similar al siguiente:

Y obviamente, si obtenemos todos nuestros empleados, veremos que allí aparece el empleado que habíamos creado en un primer momento, con las modificaciones realizadas previamente.

Por cierto, a modo aclaratorio o a tener en consideración. Al realizar una petición de tipo Patch, lo habitual será recibir como respuesta un 204 No Content en el caso de que el payload de la respuesta no devuelva nada, o un 200 Ok en el caso de que sí devolvamos información.

 

Conclusiones

Como podemos observar, el uso de PATCH además de ser muy flexible, es muy sencillo de acometer.

Basta con tener cierto orden o criterio a la hora de saber qué operaciones vamos a realizar, y de qué tipo.

Tener en consideración algún aspecto sobre la lógica de negocio en la que nos encontremos, y realizar las acciones correspondientes dentro del sistema, pero en general, es muy sencillo de acometer.

Podrás acceder al código completo del proyecto de demostración en mi repositorio de GitHub en este enlace.

 

Esta entrada forma parte del 3er calendario de Adviento de C#, que encontrarás en este enlace.

Happy Coding!

Comments

Deja un comentario Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

← Previous Post Next Post →

Jorge Serrano

MVP Reconnect


¡Subscríbete a mi canal!
YouTube

Donaciones
Donation

Entradas recientes

  • Go – Arrays
  • Go – Operators
  • Go – Constants
  • Go – Tipos de Datos
  • Go – Variables
  • Hello Go-rld!
  • Introducción a Go o Golang
  • JSON Patch en ASP.NET Core 5 Web API
  • Null Checking en C#
  • ¿Porqué mi página web por defecto de ASP.NET Core no se vé en mi Azure Web App y me da un 404?

Categorías

  • .NET 5
  • .NET Core
  • .NET Core 3.0
  • .NET Core 3.1
  • .NET Framework 2.0
  • .NET Framework 3.0
  • .NET Framework 3.5
  • .NET Framework 4.0
  • .NET Framework 4.5
  • .NET Framework 4.6
  • .NET Framework 4.7
  • .NET Framework 4.8
  • .NET Standard 2.0
  • .NET Standard 2.1
  • AMQP
  • Android
  • Angular
  • API REST
  • Apple
  • Apple iOS
  • Apple macOs
  • Arquitectura
  • ASP.NET
  • ASP.NET Core
  • ASP.NET Core 3
  • ASP.NET Core 5
  • AWS
  • Azure App Service
  • Azure Application Insights
  • Azure Cosmos DB
  • Azure Database Migration Service
  • Azure Databricks
  • Azure DevOps
  • Azure Event Grid
  • Azure Functions
  • Azure IoT
  • Azure Portal
  • Azure PowerShell
  • Azure Queue Storage
  • Azure SQL
  • Azure Storage
  • Azure Virtual Datacenter
  • Azure WebApps
  • Big Data
  • Bing
  • Blazor
  • Blog
  • Bots
  • C#
  • C# 7.0
  • C# 7.1
  • C# 7.2
  • C# 7.3
  • C# 8.0
  • C# 9.0
  • Channel 9
  • Codeplex
  • Codespaces
  • Containers
  • Debugging
  • DevOps
  • Docker
  • Electron
  • Entity Framework
  • Entity Framework Core
  • Entity Framework Core 3.0
  • Entity Framework Core 5
  • Eventos
  • F#
  • FaaS
  • FeatureFlags
  • FeatureToggles
  • Feeds
  • Fluent Assertions
  • General
  • GIMP
  • Git
  • GitHub
  • Go
  • Google
  • Google Analytics
  • Gradle
  • gRPC
  • GSA
  • Historia de la Informática
  • HoloLens
  • HtmlAgilityPack
  • IdentityServer4
  • Inkscape
  • Ionic
  • iOS
  • IoT
  • Java
  • JavaScript
  • JDBC
  • JSON
  • Kubernetes
  • Lenguajes de Programación
  • Libros y Cursos
  • LINQ
  • Linux
  • LiteDB
  • Machine Learning
  • macOS
  • Microservices
  • Microsoft
  • Microsoft .NET Framework 4.5
  • Microsoft 365
  • Microsoft Azure
  • Microsoft Build
  • Microsoft Ignite
  • Microsoft Learn
  • Microsoft Orleans
  • Microsoft Surface Go
  • Microsoft Teams
  • ML.NET
  • MQTT
  • MRO
  • MS-DOS
  • MsCoders Madrid
  • MVP
  • NancyFx
  • Node.js
  • NoSQL
  • NuGet
  • NUnit
  • OData
  • ODP.NET Core
  • Office 2007
  • Office 2010
  • Office 2013
  • Office 2016
  • Office 2019
  • Office 365
  • Open Source
  • Open XML SDK
  • Opinión
  • Orchard CMS
  • OT
  • PaaS
  • Patterns
  • PdfSharpCore
  • Performance
  • PHP
  • Postman
  • Power BI
  • PowerShell
  • PowerShell Core
  • Productividad
  • Project Server 2019
  • R
  • Rendimiento
  • Scala
  • Scraper
  • Security
  • Serverless
  • Service Fabric
  • SharePoint Server 2019
  • SignalR
  • Sin categoría
  • Sistemas Distribuidos
  • Skype
  • Skype for Business Server 2019
  • Small Basic Online
  • SQL Server 2005
  • SQL Server 2008
  • SQL Server 2012
  • SQL Server 2014
  • SQL Server 2016
  • SQL Server 2017
  • SQL Server 2019
  • STOMP
  • Swagger
  • Testing
  • TFS 2017
  • TFS 2018
  • Tools
  • TypeScript
  • Unity
  • UWP
  • UX
  • Visio
  • Visual Basic
  • Visual Studio 2010
  • Visual Studio 2012
  • Visual Studio 2013
  • Visual Studio 2015
  • Visual Studio 2017
  • Visual Studio 2017 for Mac
  • Visual Studio 2019
  • Visual Studio 2019 for Mac
  • Visual Studio App Center
  • Visual Studio Code
  • Visual Studio IntelliCode
  • Visual Studio Live Share
  • Visual Studio Live Share Audio
  • Visual Studio Online
  • VS Anywhere
  • Vue.js
  • Web API
  • WebAssembly
  • WinDbg
  • Windows
  • Windows 10
  • Windows Compatibility Pack
  • Windows Phone 10
  • Windows Phone 7
  • Windows Phone 8
  • Windows Server 2008
  • Windows Server 2012
  • Windows Server 2016
  • Windows Server 2019
  • Windows Service
  • WinForms
  • WinUI
  • WPF
  • Xamarin
  • Xbox
  • Xcode
  • Xiaomi Mi Band 2
  • xUnit
  • YAML

Archivos

  • enero 2021
  • diciembre 2020
  • noviembre 2020
  • octubre 2020
  • septiembre 2020
  • agosto 2020
  • julio 2020
  • junio 2020
  • mayo 2020
  • abril 2020
  • marzo 2020
  • febrero 2020
  • enero 2020
  • diciembre 2019
  • noviembre 2019
  • octubre 2019
  • septiembre 2019
  • agosto 2019
  • julio 2019
  • junio 2019
  • mayo 2019
  • abril 2019
  • marzo 2019
  • febrero 2019
  • enero 2019
  • diciembre 2018
  • noviembre 2018
  • octubre 2018
  • septiembre 2018
  • agosto 2018
  • julio 2018
  • junio 2018
  • mayo 2018
  • abril 2018
  • marzo 2018
  • febrero 2018
  • enero 2018
  • diciembre 2017
  • noviembre 2017
  • octubre 2017
  • septiembre 2017
  • agosto 2017
  • julio 2017
  • junio 2017
  • febrero 2015
  • octubre 2014
  • junio 2014
  • marzo 2014
  • febrero 2014
  • enero 2014
  • diciembre 2013
  • septiembre 2013
  • agosto 2013
  • julio 2013
  • junio 2013
  • abril 2013
  • febrero 2013
  • enero 2013
  • diciembre 2012
  • noviembre 2012
  • septiembre 2012
  • agosto 2012
  • junio 2012
  • mayo 2012
  • abril 2012
  • marzo 2012
  • febrero 2012
  • enero 2012
  • diciembre 2011
  • noviembre 2011
  • octubre 2011
  • septiembre 2011
  • agosto 2011
  • julio 2011
  • junio 2011
  • mayo 2011
  • abril 2011
  • marzo 2011
  • enero 2011
  • diciembre 2010
  • noviembre 2010
  • octubre 2010
  • septiembre 2010
  • agosto 2010
  • julio 2010
  • junio 2010
  • mayo 2010
  • abril 2010
  • marzo 2010
  • febrero 2010
  • enero 2010
  • diciembre 2009
  • noviembre 2009
  • octubre 2009
  • septiembre 2009
  • agosto 2009
  • julio 2009
  • junio 2009
  • mayo 2009
  • abril 2009
  • marzo 2009
  • febrero 2009
  • enero 2009
  • diciembre 2008
  • noviembre 2008
  • octubre 2008
  • septiembre 2008
  • agosto 2008
  • julio 2008
  • junio 2008
  • mayo 2008
  • abril 2008
  • marzo 2008
  • febrero 2008
  • enero 2008
  • diciembre 2007
  • noviembre 2007
  • octubre 2007
  • septiembre 2007
  • agosto 2007
  • julio 2007
  • junio 2007
  • mayo 2007
  • abril 2007
  • marzo 2007
  • febrero 2007
  • enero 2007
  • diciembre 2006
  • noviembre 2006
  • octubre 2006
  • septiembre 2006
  • agosto 2006
  • julio 2006
  • junio 2006
  • mayo 2006
About This Site

A cras tincidunt, ut tellus et. Gravida scel ipsum sed iaculis, nunc non nam. Placerat sed phase llus, purus purus elit.

Archives Widget
  • January 2010
  • December 2009
  • November 2009
  • October 2009
Categories
  • Entertainment
  • Technology
  • Sports & Recreation
  • Jobs & Lifestyle
Search
  • twitter

Powered by WordPress  |  Business Directory by InkThemes.

This site uses cookies: Find out more.