login register Sysop! about ME  
qrcode
    최초 작성일 :    2015년 04월 13일
  최종 수정일 :    2015년 04월 13일
  작성자 :    Taeyo
  편집자 :    Taeyo (김 태영)
  읽음수 :    19,840

강좌 목록으로 돌아가기

필자의 잡담~

안녕하세요, Taeyo입니다.

지난 번 이후로 금새 올리게 되었네요. 앞으로도 이런 페이스이면 참 좋을텐데 말이죠 ㅎㅎ
Web API 2와 관련한 두번째 글입니다. 다만 이게 공식적으로 순서가 있는 상태가 아니라서 제가 알아서
판단해서 일단 시리즈처럼 번역해 올리려 하고 있습니다. 참고해 주시고요. 즐겨주세요~
본 번역문서는 ASP.NET 기술을 널리 알리고자 하는 개인적인 취지로 번역되어 제공되는 문서로, 원문을 비롯한 모든 저작권은 마이크로소프트사에 있습니다. 마이크로소프트사의 요청이 있을 경우, 언제라도 게시가 중단될 수 있습니다. 본 번역문서에는 오역이 포함되어 있을 수 있으며 주석도 번역자 개인의 견해일뿐입니다. 마이크로소프트사는 본 문서의 번역된 내용에 대해 일체의 보장을 하지 않습니다. 번역이 완료된 뒤에도 제품이 업그레이드 되거나 기능이 변경됨에 따라 원문도 변경되거나 보완되었을 수 있으므로 참고하시기 바랍니다.

이번 주제는 ASP.NET Web API에서 응답 메시지를 반환하는 경우, 반환 값을 컨트롤러 액션에서 HTTP 응답 메시지로 어떻게 변환할 수 있는 지를 설명한다.

Web API 컨트롤러 액션은 다음 중 하나의 유형을 반환할 수 있다

  1. void
  2. HttpResponseMessage
  3. IHttpActionResult
  4. 그 밖의 형식

이 중 어떤 것이 반환되느냐에 따라 Web API는 각기 다른 메카니즘을 사용하여 HTTP 응답을 생성한다.

반환 형식Web API가 응답을 생성하는 방법
void204(No Content)를 반환함
HttpResponseMessageHTTP 응답 메세지로 직접적으로 변환
IHttpActionResultHttpResponseMessage를 생성하기 위해서 ExecuteAsync를 호출한 뒤, HTTP 응답 메세지로 변환
그 밖의 형식직렬화된 반환 값을 응답 본문에 작성; 200(OK)를 반환

이번 글에서는 이러한 각각의 옵션에 대해서는 자세히 다룰 예정이다

void

만일 반환 형식이 void라면, Web API는 단순히 비어있는 HTTP 응답을 상태코드 204(No Content)와 함께 반환한다.

컨트롤러 예제 :

public class ValuesController : ApiController
{
    public void Post()
    {
    }
}

HTTP 응답 :

HTTP/1.1 204 No Content
Server: Microsoft-IIS/8.0
Date: Mon, 27 Jan 2014 02:13:26 GMT

HttpResponseMessage

만일 액션이 HttpResponseMessage를 반환한다면, Web API는 반환 값을 HTTP 응답 메세지로 곧바로 변환하게 되는데, 응답 메세지는 HttpResponseMessage 개체의 속성들을 사용하여 구성한다.

이 옵션을 사용하면 응답 메세지에 다양한 설정을 추가할 수가 있는데, 예를 들면 다음 컨트롤러 액션은 Cache-Control 헤더를 설정하는 예이다.

public class ValuesController : ApiController
{
    public HttpResponseMessage Get()
    {
        HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, "value");
        response.Content = new StringContent("hello", Encoding.Unicode);
        response.Headers.CacheControl = new CacheControlHeaderValue()
        {
            MaxAge = TimeSpan.FromMinutes(20)
        };
        return response;
    } 
}

응답 :

HTTP/1.1 200 OK
Cache-Control: max-age=1200
Content-Length: 10
Content-Type: text/plain; charset=utf-16
Server: Microsoft-IIS/8.0
Date: Mon, 27 Jan 2014 08:53:35 GMT

hello

만약 도메인 모델을 CreateResponse 메서드로 전달한다면 Web API는 media formatter를 사용해서 직렬화된 모델을 응답 본문에 작성하게 된다.

public HttpResponseMessage Get()
{
    // Get a list of products from a database.
    IEnumerable<Product> products = GetProductsFromDB();
    // Write the list to the response body.
    HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, products);
    return response;
}

Web API는 요청에 포함되어 있는 Accept 헤더를 사용하여 적절한 포매터를 선택한다. 이에 대한 좀 더 자세한 내용은 Content Negotiation를 참고하자.

IHttpActionResult

IHttpActionResult 인터페이스는 Web API 2에서 처음 소개된 녀석으로서 기본적으로 HttpResponseMessage 팩토리를 정의하고 있다. 다음은 IHttpActionResult 인터페이스를 사용할 경우 얻을 수 있는 몇몇 장점이다 :

  • 여러분의 컨트롤러에 대한 단위 테스트를 용이하게 한다
  • HTTP 응답을 생성하는 공통 로직들을 별개의 클래스로 옮길 수 있다.
  • 컨트롤러 액션의 의도를 명확하게 만들 수 있다(응답을 구성하는 저수준의 복잡한 내용들을 드러나지 않도록 하여)

IHttpActionResult는 단일 메서드로서 ExecuteAsync를 갖고 있는데, 이는 비동기적으로 HttpResponseMessage 인스턴스를 생성한다.

public interface IHttpActionResult
{
    Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken);
} 

만일 컨트롤러 액션이 IHttpActionResult를 반환한다면, Web API는 ExecuteAsync 메서드를 호출하여 HttpResponseMessage를 생성한 다음 그를 HTTP 응답 메세지로 변환한다

다음은 일반적인 텍스트 응답을 생성하는 간단한 IHttpActionResult의 구현 예이다 :

public class TextResult : IHttpActionResult
{
    string _value;
    HttpRequestMessage _request;
    public TextResult(string value, HttpRequestMessage request)
    {
        _value = value;
        _request = request;
    }
    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage()
        {
            Content = new StringContent(_value),
            RequestMessage = _request
        };
        return Task.FromResult(response);
    }
}

예제 컨트롤러 액션 :

public class ValuesController : ApiController
{
    public IHttpActionResult Get()
    {
        return new TextResult("hello", Request);
    }
}

응답 :

HTTP/1.1 200 OK
Content-Length: 5
Content-Type: text/plain; charset=utf-8
Server: Microsoft-IIS/8.0
Date: Mon, 27 Jan 2014 08:53:35 GMT

hello

예상보다 자주 여러분은 System.Web.Http.Results 네임스페이스에 정의되어 있는 IHttpActionResult 구현을 사용하게 될 것이다. 그렇기에, ApiContoller 클래스는 이러한 내장된 액션 결과들을 반환하는 도우미 메서드들도 제공해주고 있다.

다음 예제에서는 요청된 제품의 ID가 존재하지 않을 경우 404(Not Found) 응답을 제공하기 위해서 컨트롤러가 ApiController.NotFound를 호출하는 예를 보여주고 있다. 그리고, 만일 제품이 존재한다면 제품 정보를 포함하여 200 (OK) 응답을 생성하는 ApiController.OK를 호출하고 있다.

public IHttpActionResult Get (int id)
{
    Product product = _repository.Get (id);
    if (product == null)
    {
        return NotFound(); // Returns a NotFoundResult
    }
    return Ok(product);  // Returns an OkNegotiatedContentResult
}

그 밖의 반환 형식

그 밖의 모든 반환 형식들에 대해서는 Web API가 미디어 포매터(media formatter)를 사용하여 반환 값을 직렬화한다. Web API는 직렬화된 값을 응답 본문에 작성하며, 이 경우 응답 상태 코드는 200(OK)이다.

public class ProductsController : ApiController
{
    public IEnumerable<Product> Get()
    {
        return GetAllProductsFromDB();
    }
}

이 방식의 문제점은 에러 코드(예를 들면, 404)를 직접 반환할 수가 없다는 점이다. 하지만, HttpResponseException를 던지는 방식으로 이 문제를 우회할 수 있긴 할 것이다. 더 자세한 내용은 Exception Handling in ASP.NET Web API를 참고하도록 하자.

더불어, Web API는 요청 안에 포함되어 있는 Accept 헤더를 확인하여 적절한 포매터를 결정한다.이에 대한 자세한 내용은 Content Negotiation를 참고하도록 하자.

요청 예

GET http://localhost/api/products HTTP/1.1
User-Agent: Fiddler
Host: localhost:24127
Accept: application/json

응답 예 :

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
Date: Mon, 27 Jan 2014 08:53:35 GMT
Content-Length: 56

[{"Id":1,"Name":"Yo-yo","Category":"Toys","Price":6.95}]

authored by

  itist
  2015-04-13(10:57)
캐릭 이미지
감사합니다!

 
 
.NET과 Java 동영상 기반의 교육사이트

로딩 중입니다...

서버 프레임워크 지원 : NeoDEEX
based on ASP.NET 3.5
Creative Commons License
{5}
{2} 읽음   :{3} ({4})