연습 - 컨트롤러 추가

완료됨

Controlleractions라는 하나 이상의 공용 메서드가 있는 공용 클래스입니다. 규칙에 따라 컨트롤러는 프로젝트 루트의 Controllers 디렉터리에 배치됩니다. 동작은 웹 API 컨트롤러 내에서 HTTP 엔드포인트로 표시됩니다.

컨트롤러 만들기

  1. Visual Studio Code에서 Controllers 폴더를 선택하고 PizzaController.cs라는 새 파일을 추가합니다.

    Controllers 폴더에 새 파일을 추가하는 방법을 보여주는 Visual Studio Code의 스크린샷.

    빈 클래스 파일인 PizzaController.csControllers 디렉터리에 만들어집니다. Controllers 디렉터리 이름은 규칙입니다. 디렉터리 이름은 웹 API가 사용하는 model-view-controller 아키텍처에서 가져온 것입니다.

    참고

    규칙에 따라 컨트롤러 클래스 이름 뒤에는 Controller가 붙습니다.

  2. Controllers/PizzaController.cs에 다음 코드를 추가합니다. 변경 내용을 저장합니다.

    using ContosoPizza.Models;
    using ContosoPizza.Services;
    using Microsoft.AspNetCore.Mvc;
    
    namespace ContosoPizza.Controllers;
    
    [ApiController]
    [Route("[controller]")]
    public class PizzaController : ControllerBase
    {
        public PizzaController()
        {
        }
    
        // GET all action
    
        // GET by Id action
    
        // POST action
    
        // PUT action
    
        // DELETE action
    }
    

    앞서 배운 것처럼, 이 클래스는 HTTP 요청 ASP.NET Core와 작동하는 기본 클래스인 ControllerBase에서 파생됩니다. 또한 학습한 두 가지 표준 특성인 [ApiController][Route]도 포함됩니다. 이전과 마찬가지로 [Route] 특성은 [controller] 토큰에 대한 매핑을 정의합니다. 이 컨트롤러 클래스의 이름은 PizzaController이므로 이 컨트롤러는 https://localhost:{PORT}/pizza에 대한 요청을 처리합니다.

모든 피자 받기

구현해야 하는 첫 번째 REST 동사는 클라이언트가 API에서 모든 피자를 가져올 수 있는 GET입니다. 기본 제공된 [HttpGet] 특성을 사용하여 서비스에서 피자를 반환하는 메서드를 정의할 수 있습니다.

Controllers/PizzaController.cs에서 // GET all action 주석을 다음 코드로 교체합니다.

[HttpGet]
public ActionResult<List<Pizza>> GetAll() =>
    PizzaService.GetAll();

이전 동작:

  • [HttpGet] 특성으로 표시된 대로 HTTP GET 동사에만 응답합니다.
  • List<Pizza> 유형의 ActionResult 인스턴스를 반환합니다. ActionResult 형식은 ASP.NET Core의 모든 작업 결과에 대한 기본 클래스입니다.
  • 모든 피자에 대해 서비스를 쿼리하고 application/jsonContent-Type 값을 통해 데이터를 자동으로 반환합니다.

단일 피자 검색

클라이언트는 전체 목록 대신 특정 피자에 대한 정보를 요청할 수도 있습니다. id 매개 변수가 필요한 다른 GET 작업을 구현할 수 있습니다. 기본 제공된 [HttpGet("{id}")] 특성을 사용하여 서비스에서 피자를 반환하는 메서드를 정의할 수 있습니다. 라우팅 논리는 [HttpGet](id 제외) 및 [HttpGet("{id}")](id 포함)을 두 개의 다른 경로로 등록합니다. 그런 다음, 별도의 작업을 작성하여 단일 항목을 검색할 수 있습니다.

Controllers/PizzaController.cs에서 // GET by Id action 주석을 다음 코드로 교체합니다.

[HttpGet("{id}")]
public ActionResult<Pizza> Get(int id)
{
    var pizza = PizzaService.Get(id);

    if(pizza == null)
        return NotFound();

    return pizza;
}

이전 동작:

  • [HttpGet] 특성으로 표시된 대로 HTTP GET 동사에만 응답합니다.
  • id 매개 변수의 값이 pizza/ 다음의 URL 세그먼트에 포함되도록 요구합니다. 컨트롤러 수준 [Route] 특성이 /pizza 패턴을 정의했습니다.
  • 데이터베이스에 제공된 id 매개 변수와 일치하는 피자를 쿼리합니다.

앞의 작업에 사용된 각각의 ActionResult 인스턴스는 다음 표의 해당 HTTP 상태 코드로 매핑됩니다.

ASP.NET Core
동작 결과
HTTP 상태 코드 설명
Ok가 암시됩니다. 200 제공된 id 매개 변수와 일치하는 제품은 메모리 내 캐시에 존재합니다.
accept HTTP 요청 헤더(기본적으로 JSON)에 정의된 대로 미디어 유형의 응답 본문에 제품이 포함됩니다.
NotFound 404 제공된 id 매개 변수와 일치하는 제품은 메모리 내 캐시에 존재하지 않습니다.

새 컨트롤러 빌드 및 실행

다음 명령을 실행하여 웹 API를 빌드하여 시작합니다.

dotnet run

Http 파일을 사용하여 컨트롤러 테스트

  1. ContosoPizza.http 열기

  2. GET을 추가하여 ### 구분 기호에서 Pizza 엔드포인트를 호출합니다.

    GET {{ContosoPizza_HostAddress}}/pizza/
    Accept: application/json
    
    ###
    
  3. 이 새 GET 호출 위에서 요청 보내기 명령을 선택합니다.

    앞의 명령은 JSON의 모든 피자 목록을 반환합니다.

    HTTP/1.1 200 OK
    Connection: close
    Content-Type: application/json; charset=utf-8
    Date: Wed, 17 Jan 2024 16:57:09 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    [
        {
            "id": 1,
            "name": "Classic Italian",
            "isGlutenFree": false
        },
        {
            "id": 2,
            "name": "Veggie",
            "isGlutenFree": true
        }
    ]   
    
  4. 단일 피자를 쿼리하려면 다른 GET 요청을 할 수 있지만, 다음 명령을 사용하여 id 매개 변수를 전달합니다.

    GET {{ContosoPizza_HostAddress}}/pizza/1
    Accept: application/json
    
    ###
    

    앞의 명령은 다음 출력과 함께 Classic Italian을 반환합니다.

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Date: Fri, 02 Apr 2021 21:57:57 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    {
        "id": 1,
        "name": "Classic Italian",
        "isGlutenFree": false
    }
    
  5. 또한 API는 항목이 없는 상황을 처리합니다. API를 다시 호출하지만 다음 명령을 사용하여 잘못된 피자 id 매개 변수를 전달합니다.

    GET {{ContosoPizza_HostAddress}}/pizza/5
    Accept: application/json
    
    ###
    

    앞의 명령은 다음 출력과 함께 404 Not Found 오류를 반환합니다.

    HTTP/1.1 404 Not Found
    Content-Type: application/problem+json; charset=utf-8
    Date: Fri, 02 Apr 2021 22:03:06 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    {
        "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
        "title": "Not Found",
        "status": 404,
        "traceId": "00-ec263e401ec554b6a2f3e216a1d1fac5-4b40b8023d56762c-00"
    }
    

이제 GET 동사 구현을 완료했습니다. 다음 단원에서는 피자 데이터에 대한 CRUD 작업을 지원하기 위해 PizzaController에 더 많은 작업을 추가할 수 있습니다.

선택 사항: 명령줄 HTTP REPL(Read-Eval-Print Loop)을 사용하여 컨트롤러 테스트

  1. 기존 httprepl 터미널을 열거나 주 메뉴에서 터미널>새 터미널을 선택하여 Visual Studio Code에서 새 통합 터미널을 엽니다.

  2. 다음 명령을 실행하여 웹 API에 연결합니다.

    httprepl https://localhost:{PORT}
    

    또는 HttpRepl이 실행 중인 동안 언제든지 다음 명령을 실행합니다.

    connect https://localhost:{PORT}
    
  3. 새로 사용 가능한 Pizza 엔드포인트를 보려면 다음 명령을 실행합니다.

    ls
    

    앞의 명령은 연결된 엔드포인트에서 사용할 수 있는 모든 API를 검색합니다. 다음 코드가 표시되어야 합니다.

     https://localhost:{PORT}/> ls
     .                 []
     Pizza             [GET]
     WeatherForecast   [GET]
    
  4. 다음 명령을 실행하여 Pizza 엔드포인트로 이동합니다.

    cd Pizza
    

    앞의 명령은 Pizza 엔드포인트에 대해 사용 가능한 API의 출력을 보여줍니다.

    https://localhost:{PORT}/> cd Pizza
    /Pizza    [GET]
    
  5. 다음 명령을 사용하여 HttpRepl에서 GET 요청을 합니다.

    get
    

    앞의 명령은 JSON의 모든 피자 목록을 반환합니다.

      HTTP/1.1 200 OK
      Content-Type: application/json; charset=utf-8
      Date: Fri, 02 Apr 2021 21:55:53 GMT
      Server: Kestrel
      Transfer-Encoding: chunked
    
      [
          {
              "id": 1,
              "name": "Classic Italian",
              "isGlutenFree": false
          },
          {
              "id": 2,
              "name": "Veggie",
              "isGlutenFree": true
          }
      ]
    
  6. 단일 피자를 쿼리하려면 다른 GET 요청을 할 수 있지만, 다음 명령을 사용하여 id 매개 변수를 전달합니다.

    get 1
    

    앞의 명령은 다음 출력과 함께 Classic Italian을 반환합니다.

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Date: Fri, 02 Apr 2021 21:57:57 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    {
        "id": 1,
        "name": "Classic Italian",
        "isGlutenFree": false
    }
    
  7. 또한 API는 항목이 없는 상황을 처리합니다. API를 다시 호출하지만 다음 명령을 사용하여 잘못된 피자 id 매개 변수를 전달합니다.

    get 5
    

    앞의 명령은 다음 출력과 함께 404 Not Found 오류를 반환합니다.

    HTTP/1.1 404 Not Found
    Content-Type: application/problem+json; charset=utf-8
    Date: Fri, 02 Apr 2021 22:03:06 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    {
        "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
        "title": "Not Found",
        "status": 404,
        "traceId": "00-ec263e401ec554b6a2f3e216a1d1fac5-4b40b8023d56762c-00"
    }
    
  8. Visual Studio Code의 드롭다운 목록의 dotnet 터미널로 돌아가서 키보드에서 CTRL+C를 선택하여 웹 API를 종료합니다.

이제 GET 동사 구현을 완료했습니다. 다음 단원에서는 피자 데이터에 대한 CRUD 작업을 지원하기 위해 PizzaController에 더 많은 작업을 추가할 수 있습니다.