it-source

aspnet core api에서 Created(또는 CreatedAtAction/CreatedAtRoute)를 사용하는 방법

criticalcode 2023. 7. 30. 17:55
반응형

aspnet core api에서 Created(또는 CreatedAtAction/CreatedAtRoute)를 사용하는 방법

새로 생성된 객체의 위치에 대해 소비자에게 제 api를 알려드리고 싶습니다.난 있는 걸 안다.Created() CreatedAtRoute()그리고.CreatedAtAction()어떻게 사용해야 할지 잘 모르겠습니다.

제가 시도한 것은 다음과 같습니다.

가리키고 싶은 Get 리소스가 있습니다.ID를 입력으로 사용합니다.

    [HttpGet("/${id}", Name = "GetProduct")]
    [ProducesResponseType(typeof(Produkt), 200)]
    public IActionResult Get([FromRoute] int id)
    {
       // some code...
        return Ok(...);
    }

POST 경로를 통해 제품이 생성되면 위치 헤더를 통해 다음 리소스를 가리킵니다.

시도 1

    [HttpPost]
    [ProducesResponseType(typeof(Produkt), 200)]
    public IActionResult CreateNewProduct([FromBody] ProduktDtoForCreate productFromBody)
    {
        //...
        return CreatedAtRoute("GetProduct", new { id = productToCreate.Id }, productToCreate);
    }

위치 헤더 http://localhost:5000/$15003을 반환합니다.

시도 2

    [HttpPost]
    [ProducesResponseType(typeof(Produkt), 200)]
    public IActionResult CreateNewProduct([FromBody] ProduktDtoForCreate productFromBody)
    {
        //...
        return Created(new Uri($"{Request.Path}/{productToCreate.Id}", UriKind.Relative), productToCreate);
    }

이것은 작동하고 /api/v1.0/productkte/16004를 반환하지만 현재 요청을 사용하여 새 위치를 가리킬 필요가 없는 것 같습니다.또한 이것이 좋은 관행인지 잘 모르겠습니다.

CreatedAtAction제 생각에는 최고의 결과물을 제공합니다.다음 컨트롤러 코드는 필요한 작업을 수행합니다.

[Route("api/products")]
[ApiController]
public class ProductsController : ControllerBase
{
    private readonly IProductRepository productRepository;

    public ProductsController(IProductRepository productRepository)
    {
        this.productRepository = productRepository;
    }

    [HttpPost]
    [Route("")]
    [ProducesResponseType(StatusCodes.Status201Created)]
    public ActionResult<Product> CreateProduct(ProductCreateDto product)
    {
        if (product is null)
            return BadRequest(new ArgumentNullException());

        var entity = productRepository.CreateProduct(product);

        return CreatedAtAction(nameof(GetProduct), new { id = entity.ID }, entity);
    }

    [HttpGet]
    [Route("{id}")]
    public ActionResult<Product> GetProduct(int id)
    {
        return productRepository.GetProduct(id);
    }
}

다음 요청 발행:

POST http://localhost:5000/api/products HTTP/1.1 
Host: localhost:5000
Connection: keep-alive 
Content-Length: 25 
Content-Type: application/json

{ "name": "ACME Widget" }

다음과 같은 응답을 얻을 수 있습니다.

HTTP/1.1 201 Created
Date: Mon, 12 Oct 2020 09:50:00 GMT
Content-Type: application/json; charset=utf-8
Server: Kestrel
Content-Length: 29
Location: http://localhost:5000/api/products/1

{"id":1,"name":"ACME Widget"}

Get 메서드에 대한 경로에서 선행 / 및 $ out(즉, "{id}"이어야 함)을 모두 사용합니다.앞에 /가 있으면 경로가 응용 프로그램의 기본 경로에 상대적이 되고, 경로를 제거하면 대신 컨트롤러의 기본 경로에 상대적인 메소드 경로가 됩니다.$는 경로에서 리터럴 문자로 처리되므로 시도 1의 위치 헤더에 나타나는 이유입니다.변경한 후에는 CreatedAtRoute 통화가 예상대로 작동하는지 확인해야 합니다.

RFC 7231 인용:

201(생성됨) 상태 코드는 요청이 충족되어 하나 이상의 새 리소스가 생성되었음을 나타냅니다.요청에 의해 생성된 기본 리소스는 응답의 위치 헤더 필드 또는 수신된 위치 필드가 없는 경우 유효 요청 URI로 식별됩니다.

리소스를 식별하는 방법은 컨텍스트에 따라 다릅니다.생성된 리소스가 다음 위치에 상주하는 경우<request_uri>/<id>식별자는 정당할 수 있습니다.<id>.

언급URL : https://stackoverflow.com/questions/47939945/how-to-use-created-or-createdataction-createdatroute-in-an-asp-net-core-api

반응형