zoukankan      html  css  js  c++  java
  • 使用.NET Core在RESTful API中进行路由操作

    介绍

    当列出REST API的最佳实践时,Routing(路由)总是使它位于堆栈的顶部。今天,在这篇文章中,我们将使用特定于.NET Core的REST(web)API来处理路由概念。

    对于新手API开发人员,技术顾问以及与REST API相关的所有其他IT专业人员(尤其是使用Microsoft技术堆栈),本文将解释使用Microsoft .NET Core在REST API中重点关注属性路由的重要性和功能。

    概论

    路由是开发者社区中众多公开争论的话题,这是一个有趣的功能,可以深入研究。路由是API使用的基于功能的标记或Uri模板,以匹配期望执行的所需操作或方法。在开发过程中有两种类型或两种不同类型的路由。也就是说,'Convention-Based Routing'是REST路由家族中的长子,之后是'Attribute Routing',是迄今为止最可爱的儿子。如前所述,在API开发和设计阶段,使用哪种类型的路由机制是一个值得讨论的话题。

    在“基于约定的路由”中,路由模板是由开发人员根据需要定义的,基本上是一组带有参数的文本类型的字符串。收到请求后,它会尝试将请求的URI与此定义的路由模板进行匹配。使用这种路由类型的唯一好处是,模板是在应用程序解决方案结构中的单个位置定义的,在控制器和操作中虔诚地利用模板规则。

    那么,为什么属性路由很重要?是的,这不仅是重要的,而且强烈建议社区开发人员和架构师开发API。虽然基于约定的路由有其自己的优点,但是在构建一个好的API的时候,很少考虑这种类型的路由是不可取的。REST API中有通用的URI模式,这很难通过基于约定的路由来支持。考虑一组响应数据或资源,往往被分层数据或子资源夹杂着。例如。部门有员工,歌曲有歌手,电影有演员等等。在这种情况下预期的URI是,

    /电影/ 1 /演员

    在多个控制器和巨大资源的情况下,这种类型的URI虽然可以使用基于约定的路由来实现,但是以缩放和性能为代价是困难的。这是设计可扩展API的关键考虑因素。这里是另一个路由类型,属性路由,扮演一个角色。

    属性路由

    什么是属性路由?

    从技术上说,属性路由就是将路由作为一个属性附加到特定的控制器或操作方法。装饰控制器及其使用[Route]属性定义路由的方法称为属性路由。简单来说,在控制器和方法中使用[Route]属性是Attribute Routing。

    [Route(“api / customers / {id} / orders”)]

    它从Web API 2开始,现在是RESTful APIs设计和开发中最推荐和改编的路由类型。

    为什么使用属性路由?

    如名称所示,属性路由使用属性来定义路由。通过属性路由,您可以精确地控制URI,而不是基于约定的路由。以上所述的分层资源场景可以通过属性路由轻松实现,不会对API的可扩展性造成影响。

    另外,版本控制API,重载URI段和多参数类型模式可以通过属性路由轻松实现。

    使用属性路由

    控制器上的任何路由属性都会使控制器中的所有操作属性路由。为动作定义路由属性或控制器优先于传统路由。让我们更精确的.NET Core API,它默认带有属性路由。属性路由需要详细的输入来指定路由。但是,它允许更多地控制哪个路由模板适用于每个操作。

    配置

    当您使用.NET Core框架创建WEB API时,您可以在其Startup.cs文件中注意到,

    1. void Configure(IApplicationBuilder app,IHostingEnvironment env,ILoggerFactory loggerFactory){

    2. app.UseMvc();

    3. }

    在配置部分声明'app.UseMvc()',可以启用属性路由。这是.NET Core应用程序的默认配置。因此,启用.NET Core Web API的属性路由不需要显式配置。

    命名空间下面用于装饰[Route]作为属性。

    使用Microsoft.AspNetCore.Mvc;

    与Web API在MVC路由上的核心区别在于,它使用HTTP方法而不是URI路径来选择操作。属性路由还使用HTTP动作动词来根据请求定义对控制器下方法的操作。

    [HttpGet],[HttpPost],HttpPut(“{id}”)],[HttpDelete(“{id}”)]和所有其他记录的动作动词。

    在.NET Core项目中,默认情况下,控制器使用指定相应的HTTP动作动词的CRUD方法进行修饰。

    下面是由.NET Core创建的默认控制器,

    使用.NET Core在RESTful API中进行路由操作

    1. using System;

    2. using System.Collections.Generic;

    3. using System.Linq;

    4. using System.Threading.Tasks;

    5. using Microsoft.AspNetCore.Mvc;

    6. namespace WebAPIwiithCore.Controllers

    7. {

    8. [Route(“API / [Controller]” )]

    9. publicclassMoviesController:Controller

    10. {

    11. //获取api /值

    12. [HTTPGET]

    13. publicIEnumerable <string> Get()

    14. {

    15. returnnewstring [] { “value1” , “value2” };

    16. }

    17. //获取api / values / 5

    18. [HttpGet(“{id}” )]

    19. public String get(int id)

    20. {

    21. 返回“价值” ;

    22. }

    23. // POST api / values

    24. [HttpPost]

    25. publicvoid Post([FromBody] string Value)

    26. {

    27. }

    28. // PUT api / values / 5

    29. [HttpPut(“{id}” )]

    30. publicvoid Put(int id,[FromBody] string value)

    31. {

    32. }

    33. //删除api / values / 5

    34. [HttpDelete(“{id}” )]

    35. publicvoid删除(int id)

    36. {

    37. }

    38. }

    39. }

    如果您注意到,控制器类“ValuesController”是由路由装饰的,

    〔Route( “API / [Controller]”)]

    该功能是在称为路由令牌的.NET核心框架中引入的。令牌[controller]从定义路由的动作或类中替换控制器名称的值。

    这里的控制器名称是由路由控制器令牌装饰的值,

    1. [Route(“API / [Controller]” )]

    2. publicclassValuesController:Controller {...} //匹配'/ api / Values'

    现在让我们将控制器名称更改为MoviesController;

    1. [Route(“API / [Controller]” )]

    2. publicclassMoviesController:Controller {...} //现在匹配'/ api / Movies'

    在这里,URI'api / values'正在工作得更好,现在它会抛出一个错误(404找不到)。使用“api / Movies”更改URI将提供所需的响应。

    对于[行动]和[区域],各自的行动方式和领域也是如此。

    现在,让我们考虑下面的例子,

    1. [Route(“API / [Controller” )]

    2. publicclassMoviesController:Controller {

    3. [HTTPGET]

    4. publicIEnumerable <string> Get(){

    5. returnnewstring [] {

    6. “value1” ,

    7. “value2”

    8. };

    9. }

    10. [HttpPost]

    11. publicvoid Post([FromBody] string value){

    12. return;

    13. }

    14. }

    对于上面给出的代码片段,

    URI,

    1. // Get / api / Movies /将匹配方法1。

    1. // Post / api / Movies /将匹配方法2。

    请注意,这两个URI是相同的,唯一的区别在于它是如何被Get或Post方法调用的。这使Web API路由不同于MVC路由。

    模式

    让我们看一下其他几个例子,如上所述,通过属性路由来缓解。

    API版本控制

    在本例中,“Get / api / movies / v1 /”将被路由到方法1,“Get / api / movies / v2 /”将被路由到方法2。

    使用.NET Core在RESTful API中进行路由操作

    1. [Route(“API / [Controller]” )]

    2. publicclassMoviesController:Controller {

    3. [HttpGet(“v1” )]

    4. publicIEnumerable <string> Get(){

    5. returnnewstring [] {

    6. “V1.value1” ,

    7. “V1.value2”

    8. };

    9. }

    10. [HttpGet(“v2” )]

    11. publicIEnumerable <string> Get(){

    12. returnnewstring [] {

    13. “V2.value1” ,

    14. “V2.value2”

    15. };

    16. }

    17. }

    请注意,版本控制主要由不同的控制器处理。这里为了便于理解,我们倾向于用不同的方法用相同的签名来描述它。

    示例清楚地表明,属性路由是如何处理复杂情况的最简单方法。

    重载的URI

    在这个例子中,“id”是一个可以作为数字传递的参数,但是“knownited”映射到一个集合。

    1. [Route(“API / [Controller]” )]

    2. publicclassMoviesController:Controller {

    3. [HttpGet(“{id}” )]

    4. publicIEnumerable <string> Get(int id){

    5. returnnewstring [] {

    6. “V2.value1” ,

    7. “V2.value2”

    8. };

    9. }

    10. [HttpGet(“get” )]

    11. publicIEnumerable <string> Get(){

    12. returnCollections ..

    13. }

    14. }

    URI,

    1. // Get / api / Movies / 123将匹配方法1。

    1. // Get / api / Movies / notedited将匹配方法2。

    多个参数类型

    在这个例子中,“id”是一个参数,可以作为数字或字母表传递任何空闲的字符串。

    1. [Route(“API / [Controller]” )]

    2. publicclassMoviesController:Controller {

    3. [HttpGet(“{id:int}” )]

    4. publicIEnumerable <string> Get(int id){

    5. returnnewstring [] {

    6. “V2.value1” ,

    7. “V2.value2”

    8. };

    9. }

    10. [HttpGet(“id:aplha” )]

    11. publicIEnumerable <string> Get(string id){

    12. returnnewstring [] {

    13. “V2.value1” ,

    14. “V2.value2”

    15. };

    16. }

    17. }

    URI,

    1. // Get / api / Movies / 123将匹配方法1。

    1. // Get / api / Movies / abc将匹配方法2。

    上面的例子有一些需要注意的地方,

    HTTPGET( “{ID:int”)]

    提到参数数据类型被接受,被称为约束。我们将在后面的文章中通过这个。

    多个参数

    在这个例子中,'id'和'authorid'是一个可以作为数字传递的参数。

    1. [Route(“API / [Controller]” )]

    2. publicclassBooksController:Controller {

    3. [HttpGet(“{id:int} / author / {authorid:int}” )]

    4. publicIEnumerable <string> Getdetails(int id,intauthorid){

    5. returnnewstring [] {

    6. “V2.value1” ,

    7. “V2.value2”

    8. };

    9. }

    10. }

    匹配URI:// Get api / books / 1 / author / 5在给定的方法中,where 1与'id'和'5'匹配authorid。

    多个路线

    属性路由允许我们为相同的控制器和动作或方法定义多个路由。让我们用例子来理解它,

    1. [Route(“API / [Controller]” )]

    2. publicclassMoviesController:Controller {

    3. [HttpPut(“Post” )]

    4. [HttpPost(“Checkout” )]

    5. publicMovieordermovie(){

    6. return SomeValue...

    7. }

    8. }

    如示例中所示,Method'Ordermovie'返回模型类“Movie”的某个值。该方法定义了两个路由。一个带有HTTP动词Put,主要用于CRUD中的更新操作,另一个带有HTTP动词Post,用于创建或添加数据。两者都指的是相同的方法。

    在这种情况下,下面的URI将匹配路由,

    URI 1匹配// PUT api / movies /购买

    URI 2匹配//发布api /电影/结帐

    备注

    路线1和路线2用于更好的理解目的,与订购无关。

    我们甚至可以在控制器上定义多个路由。在这种情况下,来自控制器的两条路线都与两条路线相结合。看下面的例子,

    1. [Route(“api / Store” )]

    2. [Route(“API / [Controller]” )]

    3. publicclassMoviesController:Controller {

    4. [HttpPut(“post )]

    5. [HttpPost(“Checkout” )]

    6. publicMovieordermovie(){

    7. returnSomeValue..

    8. }

    9. }

    在这种情况下,下面的URI将匹配路由,

    URI 1匹配// PUT api / movies / buy&api / store / buy

    URI 2匹配//发布api /电影/结帐&api / store / checkout

    路线约束

    路由约束提供对路由中使用的匹配参数的控制。在路由中定义参数的语法是“{parameter:constraint}”。

    1. [HttpGet(“api / constraint / {id:int}” )]

    2. publicIEnumerable <string> Get(int id){

    3. returnnewstring [] {

    4. “V2.value1” ,

    5. “V2.value2”

    6. };

    7. }

    匹配路由:api / constraint / 1

    只有整数值将被路由到“有效”资源的“Get”方法。任何其他非整数值都不会受到方法的影响,比如api / constraint / abc将不会被路由。

    在这里,可能有一个问题。如果客户端调用,api / constraint / 0仍然会被路由到Get方法,这是错误的。所以为了遏制这个问题,我们可以为参数接受大于零的值添加另一个约束。这可以通过添加约束'min(1)'来实现,其中1是由“min”约束接受的参数。()“括号中可以接受参数

    我们可以通过用冒号分隔约束来在单个参数上添加多个约束。

    语法

    “{参数:约束:约束}”。

    1. [HttpGet(“api / constraint / {id:int:min(1)}” )]

    2. publicIEnumerable <string> Get(int id){

    3. returnnewstring [] {

    4. “V2.value1” ,

    5. “V2.value2”

    6. };

    7. }

    的URI

    1. api / constraint / 1||> 1将匹配。

    2. api / constraint / 0不匹配。

    3. api / constraint / -1或负数不匹配。

    类似的约束,比如字符串的'alpha',布尔值的'bool',日期时间的'datetime'值,'min','max','range'和特定范围的值等。

    属性路由功能虽然是API设计栈中最推荐的实现。从API的可扩展性到API让客户端可读,属性路由在API开发中扮演着重要的角色。Microsoft在其.NET Core框架中启用默认路由作为属性路由,关闭了使用路由的所有可能的线程差异。

  • 相关阅读:
    三元表达式 列表和字典推导式 函数对象 名称空间 作用域 global和nonlocal 函数装饰器 枚举对象
    函数参数 打散机制 字符串比较 返回值
    函数简介
    三种字符串的介绍 文件的读写
    字符编码
    数据类型及其常用方法 数据类型转换 可变与不可变 值拷贝与深浅拷贝
    流程控制 while和for循环
    变量命名规范 常量 输入和输出 注释 数据类型 运算符 逻辑运算符
    语言分类 编译型和解释型语言分析 环境变量 代码执行的方式 pip介绍 变量
    Python django tests
  • 原文地址:https://www.cnblogs.com/tianfengcc/p/7851871.html
Copyright © 2011-2022 走看看