【问题标题】:Rest API architecture special casesRest API 架构特例
【发布时间】:2021-04-21 06:15:51
【问题描述】:

在 .net 5 中使用 Web API 并在 rest 中符合 api 给我带来了一些挑战,即在不同控制器中拆分方法的程度和命名约定。

我已经读到,如果我的系统中有用户并且正在做一个休息架构,我的控制器将被命名为 UserController 并且获取用户的方法是:

[HttpGet("{id}")]
public string Get(int id)
{
   return "value";
}

获取用户列表:

[HttpGet]
public IEnumerable<string> Get()
{
    return new string[] { "value1", "value2" };
}

更新将是:

[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}

Delete 会有一个 [HttpDelete],依此类推。 但是特殊情况呢?

  1. 如果我想要 GetUserByUsername 怎么办?那么它会在同一个 UserController 中并且只是以下内容,还是会破坏 REST 模式?:

    [HttpGet("{用户名}")] 公共任务GetByUsername(字符串用户名) { }

  2. 如果我需要调用 api 获取一些数据来填充“createuser 页面”,假设我需要可以创建用户的角色和一些其他信息,并且希望在一次调用中完成。然后我可以在 UserController 中创建一个“InitCreateUser”而不破坏 REST 模式吗?

    [HttpPost] 公共任务 InitCreateUser() { }

  3. 如果我需要 Login 和 Logout 方法怎么办,它会是 AutenticationController 并且只有两种方法:(它与其他模式相距甚远,因为它不被称为 Get() Post() 等等)

    [HttpPost] 公共任务登录(LoginRequest 请求) { }

    [HttpPost] 公共任务注销(LogoutRequest 请求) { }

【问题讨论】:

    标签: rest asp.net-web-api


    【解决方案1】:

    是的,您可以将它放在与用户打交道的同一控制器中,并且将涉及特定实体的功能保持在同一位置是一个好习惯。

    但这显然存在具有不同端点(例如 Id 和用户名)的问题。一个简单的方法是指明您要使用哪个:

    [HttpGet("Id/{id}")]
    public string Get([FromRoute] int id) {...}
    
    -> api/User/Id/293
    
    
    [HttpGet("Username/{username}")]
    public string Get([FromRoute] string username) {...}
    
    -> api/User/Username/Tom
    

    另一种方法是有一个基本请求并让其他功能成为它的分支

    [HttpGet("{id}")]
    public string Get([FromRoute] int id) {...}
    
    -> api/User/293
    
    
    [HttpGet("Username/{username}")]
    public string Get([FromRoute] string username) {...}
    
    -> api/User/Username/Tom
    
    
    [HttpGet("Customer/{custNo}")]
    public string Get([FromRoute] string custNo) {...}
    
    -> api/User/Customer/5DtU22D
    

    但是假设您拥有用户的 ID,并且您希望执行其他功能,例如从用户那里获取相关数据以显示,但不是全部。或者您想检查特定功能的所有相关数据, 那么你可以这样做:

    [HttpGet("{id}/Permissions")]
    public PermissionModel GetUserPermission([FromRoute] int id) {...}
    
    [HttpPut("{id}/Permissions")]
    public bool UpdateUserPermission([FromRoute] int id, [FromBody] PermissionModel permission) {...}
    

    甚至更进一步的派生功能

    [HttpGet("{id}/Account")]
    public string GetUserAccount([FromRoute] int id) {...}
    
    [HttpGet("{id}/Account/Funds")]
    public double GetUserAccountTotal([FromRoute] int id) {...}
    

    如果您正在访问列表属性,例如用户有多个帐户,您可以添加辅助键:

    [HttpGet("{id}/Accounts")]
    public IEnumerable<string> GetUserAccount([FromRoute] int id) {...}
    
    [HttpGet("{id}/Accounts/{accountId}/Funds")]
    public double GetUserAccountTotal([FromRoute] int id, [FromRoute] int accountId) {...}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-04
      • 1970-01-01
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-06
      • 1970-01-01
      相关资源
      最近更新 更多