在 .NET Core 中构建 REST API (5)

就像 GET 404 响应一样,表示该资源不可用于更新,但这可能在稍后发生改变。另外,ASP.NET 提供现成的模型绑定验证。接下来,尝试一下使用错误的数据更新现有资源。

下面的 JSON 是您可能看到的 Bad Request 的响应:

{ "errors": { "Price": ["The price field is required."] }, "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "|c445a409-43564e0626f9af50." }

PATCH 是所有动词中最复杂的,因为它通过 JSON Patch 文档仅更新资源的一部分。

庆幸的是 .NET Core 提供了一个 NuGet 包:

dotnet add package Microsoft.AspNetCore.Mvc.NewtonsoftJson

然后,在 ConfigureServices 中启用它:

services.AddControllers().AddNewtonsoftJson();

下面是 PATCH Endpoint,记得添加 using Microsoft.AspNetCore.JsonPatch:

[HttpPatch] [Route("{productNumber}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public ActionResult<Product> PatchProduct([FromRoute] string productNumber, [FromBody] JsonPatchDocument<Product> patch) { try { var productDb = _context.Products .FirstOrDefault(p => p.ProductNumber.Equals(productNumber, StringComparison.InvariantCultureIgnoreCase)); if (productDb == null) return NotFound(); patch.ApplyTo(productDb, ModelState); if (!ModelState.IsValid || !TryValidateModel(productDb)) return ValidationProblem(ModelState); _context.SaveChanges(); return Ok(productDb); } catch (Exception e) { _logger.LogWarning(e, "Unable to PATCH product."); return ValidationProblem(e.Message); } }

我希望您看到一种含有不同状态码响应类型的模式开始浮现。200 OK 表示成功,400 Bad Request 表示用户错误。当 patch 被应用后,将会在 ModelState 中追加所有的验证错误。仔细看一下进行模型绑定的 JsonPatchDocument 和 应用更改的 ApplyTo。这就是将 JSON Patch 文档应用到数据库中现有产品的方式。像所有其它 Endpoints 一样,异常会被记录并包含在响应中。与其它动词一样,404 (Not Found) 响应表示相同的情形。响应状态码的一致性有助于客户端处理所有可能的场景。

一个 JSON patch 请求的 body 大概如下所示:

[{ "op": "replace", "path": "price", "value": 13.67 }]

模型绑定验证规则依然适用于 patch 操作,以保持数据的完整性。请注意,patch 操作被包装在一个数组中,因此它支持任意的操作列表。

下图是 curl 中请求 PATCH 的结果:

PATCH in curl

最后一站,DELETE 方法:

[HttpDelete] [Route("{productNumber}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult<Product> DeleteProduct([FromRoute] string productNumber) { var productDb = _context.Products .FirstOrDefault(p => p.ProductNumber.Equals(productNumber, StringComparison.InvariantCultureIgnoreCase)); if (productDb == null) return NotFound(); _context.Products.Remove(productDb); _context.SaveChanges(); return NoContent(); }

它的状态码响应是 No Content:

HTTP/1.1 204 No Content Date: Tue, 14 Jul 2020 22:59:20 GMT Server: Kestrel api-supported-versions: 1.0

此状态向客户端发出信号,表示资源不再可用,因为响应主体为空。如果需要异步后台进程来清理数据,则响应也可以为 204 (Accepted)。在实际系统中,有时最好使用软删除,以允许在审核期间进行回滚。删除数据时,请确保遵守 GPDR 或适用于该数据的任一策略。

总结

.NET Core 在您的工具袋中添加许多有用的特性,从而让使用 REST API 变得更加轻松,将诸如文档、验证、日志记录和 PATCH 请求等复杂的用例变得更易于实现。


作者 : Camilo Reyes
译者 : 技术译民
出品 : 技术译站
链接 : 英文原文

https://www.red-gate.com/simple-talk/dotnet/c-programming/build-a-rest-api-in-net-core/ Build a REST API in .NET Core

https://dotnet.microsoft.com/download/dotnet-core Download .NET Core

https://github.com/beautifulcoder/BuildRestApiNetCore 示例代码

https://rapidapi.com/blog/api-glossary/endpoint/ API Endpoints

https://semver.org/ Semantic Versioning

https://tools.ietf.org/html/rfc7807 RFC 7807 规范

https://tools.ietf.org/html/rfc6902 JSON Patch 文档

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxjsd.html