下面是一個非常簡單的 Controller ,他有一個 /auth/login 的 API 。在這個 method 中我們回傳的類型是 IActionResult:
在 Swagger UI 上面可以看到回應的範例,狀態代號為 200 ,代表成功
註: 這裡的 Swagger UI 是因為在大多數情況下在專案建立時已經自動安裝並啟用 Swashbuckle.AspNetCore 套件。
但是這個 API 在 200 的情況下是會回傳資料的,但是在上面的範例中我們無法直接的看出範例回應。
我們可以使用 ProducesResponseTypeAttribute 來標記回應的資料型態:
回應的範例,狀態代號為 200 ,代表成功,會回傳自訂的 TokenDto 物件:
假設這個 API 的 Http Code 也有可能會回應 400,不帶有其他資訊,我們可以再加上一個 ProducesResponseTypeAttribute 來標記:
假設我們使用 ActionResult 並標記資料型別:
會和手動使用 ProducesResponseTypeAttribute 標記 200 和回應資料型態的結果一樣,他可以很聰明的幫我們推斷:
但是假設我們需要標記除了 200 以外的回應,例如現在多加了一個 400 的回應:
結果 200 的回應和回應資料型態就不見了,剩下 400 手動補上的那個:
就算使用了 ActionResult ,如果想要顯示兩個或以上的回應格式,就需要手動加上 ProducesResponseTypeAttribute 並標記每一個才可以都顯示:
但是筆者喜歡在程式碼中保有一致的規範,因為 ActionResult 出現多個時還是要手動表標記,所以筆者在全部的 Controller method 中都會使用 IActionResult ,並手動替每一個 API 和每一種回應情況加上 ProducesResponseTypeAttribute。
當然,這只是筆者的做法,可以作為參考,但是在實際情況中還是要看團隊中誰的拳頭大 的規範。
參考資料:
Microsoft.Learn - Controller action return types in ASP.NET Core web API
[ApiController]
[Route("auth")]
public class AuthController : ControllerBase
{
[HttpPost("login")]
public IActionResult Login([FromBody] LoginDto dto)
{
var result = new TokenDto
{
Token = "aaa.bbb.ccc"
};
return Ok(result);
}
}
在 Swagger UI 上面可以看到回應的範例,狀態代號為 200 ,代表成功
註: 這裡的 Swagger UI 是因為在大多數情況下在專案建立時已經自動安裝並啟用 Swashbuckle.AspNetCore 套件。
但是這個 API 在 200 的情況下是會回傳資料的,但是在上面的範例中我們無法直接的看出範例回應。
我們可以使用 ProducesResponseTypeAttribute 來標記回應的資料型態:
[ApiController]
[Route("auth")]
public class AuthController : ControllerBase
{
[HttpPost("login")]
[ProducesResponseType(typeof(TokenDto), 200)]
public IActionResult Login([FromBody] LoginDto dto)
{
var result = new TokenDto
{
Token = "aaa.bbb.ccc"
};
return Ok(result);
}
}
回應的範例,狀態代號為 200 ,代表成功,會回傳自訂的 TokenDto 物件:
假設這個 API 的 Http Code 也有可能會回應 400,不帶有其他資訊,我們可以再加上一個 ProducesResponseTypeAttribute 來標記:
[ApiController]
[Route("auth")]
public class AuthController : ControllerBase
{
[HttpPost("login")]
[ProducesResponseType(typeof(TokenDto), 200)]
[ProducesResponseType(typeof(void), 400)]
public IActionResult Login([FromBody] LoginDto dto)
{
var result = new TokenDto
{
Token = "aaa.bbb.ccc"
};
return Ok(result);
}
}
假設我們使用 ActionResult 並標記資料型別:
[ApiController]
[Route("auth")]
public class AuthController : ControllerBase
{
[HttpPost("login")]
public ActionResult<TokenDto> Login([FromBody] LoginDto dto)
{
var result = new TokenDto
{
Token = "aaa.bbb.ccc"
};
return Ok(result);
}
}
會和手動使用 ProducesResponseTypeAttribute 標記 200 和回應資料型態的結果一樣,他可以很聰明的幫我們推斷:
但是假設我們需要標記除了 200 以外的回應,例如現在多加了一個 400 的回應:
[ApiController]
[Route("auth")]
public class AuthController : ControllerBase
{
[HttpPost("login")]
[ProducesResponseType(typeof(void), 400)]
public ActionResult<TokenDto> Login([FromBody] LoginDto dto)
{
var result = new TokenDto
{
Token = "aaa.bbb.ccc"
};
return Ok(result);
}
}
結果 200 的回應和回應資料型態就不見了,剩下 400 手動補上的那個:
就算使用了 ActionResult ,如果想要顯示兩個或以上的回應格式,就需要手動加上 ProducesResponseTypeAttribute 並標記每一個才可以都顯示:
[ApiController]
[Route("auth")]
public class AuthController : ControllerBase
{
[HttpPost("login")]
[ProducesResponseType(typeof(TokenDto), 200)]
[ProducesResponseType(typeof(void), 400)]
public ActionResult<TokenDto> Login([FromBody] LoginDto dto)
{
var result = new TokenDto
{
Token = "aaa.bbb.ccc"
};
return Ok(result);
}
}
結論
假設只想標記一個 API 回應格式,使用 ActionResult 並標記型態確實是一個好方式,在 Swagger UI 上面可以直接顯示,不需要多寫 ProducesResponseTypeAttribute。當有多個時再手動補充每一個即可。這時候也可以換使用 IActionResult ,因為都要每一個都標記了,所以使用 IActionResult 還比較好,才不會出現 ActionResult 標記的和 ProducesResponseTypeAttribute 200 的標記不同。但是筆者喜歡在程式碼中保有一致的規範,因為 ActionResult 出現多個時還是要手動表標記,所以筆者在全部的 Controller method 中都會使用 IActionResult ,並手動替每一個 API 和每一種回應情況加上 ProducesResponseTypeAttribute。
當然,這只是筆者的做法,可以作為參考,但是在實際情況中還是要看團隊中
參考資料:
Microsoft.Learn - Controller action return types in ASP.NET Core web API
感謝教學~
回覆刪除