Las aplicaciones ASP.NET CRUD incluyen la interacción con datos que consiste en crear, leer, actualizar y eliminar. En parte 1Configuramos un proyecto básico ASP.NET Core. En parte 2añadimos el primer leer mediante una consulta SQL++ de los datos de la lista de deseos. En parte 3añadimos otro punto final de lectura, esta vez utilizando la API de clave-valor.
Hasta este punto, las únicas modificaciones de datos que hemos hecho han sido directamente en la UI de Couchbase Capella. En este post, vamos a añadir un endpoint para manejar la creación y actualización de los datos de la lista de deseos.
SQL++ vs Clave-Valor: Revisited
SQL++ incluye INSERTAR, ACTUALIZACIÓN, BORRAR sintaxis. Así, podríamos usar SQL++ para construir un endpoint para mutar datos. Sería muy similar al código escrito en parte 2.
Una palabra clave en SQL++ que puede que no hayas visto antes es UPSERT. Como se puede adivinar, es una combinación de ACTUALIZACIÓN y INSERTAR. Se producirá una actualización si los datos ya existen; se producirá una inserción si no existen. Así es como se vería un punto final upsert usando SQL++:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[HttpPost] [Route("api/editWithSql")] public async Task<IActionResult> CreateOrEditWithSql(WishlistItem item) { var bucket = await _bucketProvider.GetBucketAsync("demo"); var cluster = bucket.Cluster; var id = item.Id ?? Guid.NewGuid(); var result = await cluster.QueryAsync<WishlistItem>( @"UPSERT INTO demo._default.wishlist (KEY, VALUE) VALUES ($id, { ""name"" : $name });", options => options .Parameter("id", id) .Parameter("name", item.Name) ); return Ok(result); } |
Hay que señalar dos cosas importantes sobre este código:
-
- Se encarga tanto de la creación como de la actualización. Si artículo tiene un ID nulo, este código asume que se está creando un nuevo elemento de la lista de deseos.
- Parametrización: al igual que en las bases de datos relacionales, SQL++ puede ser vulnerable a Inyección SQLpor lo que la parametrización es muy recomendable. Observe que la sintaxis SQL++ utiliza $ para indicar parámetros con nombre (por ejemplo $id y $name).
Este punto final funcionará. Pero como en el caso de parte 3no tenemos por qué usar SQL++ para interactuar con Couchbase. De hecho, se aplican criterios muy similares para tomar la decisión de cuándo usar key-value y cuándo usar SQL++:
| Caso práctico | ¿Clave-valor? | ¿Por qué sí o por qué no? |
| Crear un nuevo usuario con clave "73892" | Sí | Acceso directo |
| Modificar un usuario con clave "73892" | Sí | Acceso directo |
| Modificar sólo la dirección de correo electrónico de un usuario con clave "73892" | Sí | Incluso si el documento del usuario es grande, Couchbase tiene una clave basada en subdocumento APIque le permite modificar una parte del documento. |
| Modificar un grupo de usuarios con claves "73892", "47212" y "90491". | Sí | Esto puede requerir múltiples operaciones clave-valor, pero aún así puede ser más rápido que utilizar una función SQL SELECT ... WHERE ... IN consulta. |
| Modificar todas las direcciones para utilizar "OH" en lugar de "Ohio". | No | El estado del usuario es probablemente un atributo "secundario", no una clave (varios usuarios pueden ser de Ohio). Este es un buen caso de uso para un SQL++. ACTUALIZACIÓN |
Dado que este punto final sólo necesita añadir o cambiar un único elemento de la lista de deseos, vamos a utilizar la API de clave-valor en su lugar.
Escribir un punto final CreateOrEdit CRUD
Antes de pasar a la codificación, conviene pensar si Crear o editar debe ser un único punto final, o dividirse en un punto final Cree y un Editar endpoint. Para esta sencilla aplicación de lista de deseos, no hay validación, autenticación u otros problemas transversales a todo el sistema. Sin embargo, en un sistema de producción, la "adición" de datos y la "actualización" de datos pueden muy bien seguir diferentes reglas de negocio y requerir diferentes permisos. En ese caso, es posible que desee dividir las operaciones en dos puntos finales.
Por ahora, vamos a empezar con un único punto final que utiliza un "upsert":
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[HttpPost] [Route("api/edit")] public async Task<IActionResult> CreateOrEdit(WishlistItem item) { var bucket = await _bucketProvider.GetBucketAsync("demo"); var collection = await bucket.CollectionAsync("wishlist"); var id = item.Id ?? Guid.NewGuid(); await collection.UpsertAsync(id.ToString(), new { Name = item.Name }); return Ok(new { success = true}); } |
Al igual que el punto final de SQL++, este punto final examina Id para determinar si se trata de una "creación" o de una "actualización".
En UpsertAsync la función
-
- Crear un nuevo documento con id.ToString() como clave
- Modificar un documento existente con una clave de id.ToString()
En cualquier caso, una vez que este endpoint termine de ejecutarse, terminará con un documento JSON como { "nombre" = "nombre del artículo de la lista de deseos"} y un GUID como clave (técnicamente todas las claves en Couchbase son cadenas, pero sabemos que es una cadena GUID).
Nota: Una sutil diferencia entre las dos API es que la API UPSERT sólo mutará un campo (nombre), mientras que el método clave-valor UpsertAsync mutará todo el documento (que sólo es nombre por ahora).
ASP.NET CRUD en acción
Inicia tu aplicación desde Visual Studio con CTRL+F5, y deberías ver algunos nuevos endpoints aparecer en la interfaz de usuario OpenAPI / Swagger:

Desde la perspectiva de un consumidor de API, tanto /api/edit y /api/editConSql funcionarán igual. Pruébelo una vez dejando el ID en blanco para crear un nuevo elemento, luego inténtelo de nuevo con un ID conocido (utilice /api/getall si necesitas una identificación) y observa qué ocurre y qué cambia.
Por ejemplo, he añadido un nuevo elemento "Marco de fotos digital", dejando el ID en blanco (mi código .NET genera "1c3de2e7-70ea-4ee2-803b-425bbf6251cb" para mí), y actualicé el elemento con ID de "2dab198b-1836-4409-9bdf-17275a2b2462" para tener un nombre de "Camiseta Skyline Chili 2XL". Aquí están los resultados tal y como se ven en la UI de Couchbase Capella:

¿Y ahora qué?
El proyecto ASP.NET Core está conectado a Couchbase Capella, y ahora está creando/actualizando ("upserting") datos con key-value (recomendado) o SQL++ (no recomendado para esta situación específica).
En la próxima entrada del blog, completaremos el CRUD con la "D" de "eliminar"."
Mientras tanto, deberías:
-
- Prueba gratuita de Capella
- Echa un vistazo a la Couchbase Playground para .NET que puede ejecutar directamente en el navegador.