연습 - 컨트롤러 추가
Controller는 actions라는 하나 이상의 공용 메서드가 있는 공용 클래스입니다. 규칙에 따라 컨트롤러는 프로젝트 루트의 Controllers 디렉터리에 배치됩니다. 동작은 웹 API 컨트롤러 내에서 HTTP 엔드포인트로 표시됩니다.
컨트롤러 만들기
Visual Studio Code에서 Controllers 폴더를 선택하고 PizzaController.cs라는 새 파일을 추가합니다.
빈 클래스 파일인 PizzaController.cs가 Controllers 디렉터리에 만들어집니다. Controllers 디렉터리 이름은 규칙입니다. 디렉터리 이름은 웹 API가 사용하는 model-view-controller 아키텍처에서 가져온 것입니다.
참고
규칙에 따라 컨트롤러 클래스 이름 뒤에는 Controller가 붙습니다.
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]
특성으로 표시된 대로 HTTPGET
동사에만 응답합니다.List<Pizza>
유형의ActionResult
인스턴스를 반환합니다.ActionResult
형식은 ASP.NET Core의 모든 작업 결과에 대한 기본 클래스입니다.- 모든 피자에 대해 서비스를 쿼리하고
application/json
의Content-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]
특성으로 표시된 대로 HTTPGET
동사에만 응답합니다.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 파일을 사용하여 컨트롤러 테스트
ContosoPizza.http 열기
새 GET을 추가하여 ### 구분 기호에서
Pizza
엔드포인트를 호출합니다.GET {{ContosoPizza_HostAddress}}/pizza/ Accept: application/json ###
이 새 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 } ]
단일 피자를 쿼리하려면 다른
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 }
또한 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)을 사용하여 컨트롤러 테스트
기존
httprepl
터미널을 열거나 주 메뉴에서 터미널>새 터미널을 선택하여 Visual Studio Code에서 새 통합 터미널을 엽니다.다음 명령을 실행하여 웹 API에 연결합니다.
httprepl https://localhost:{PORT}
또는
HttpRepl
이 실행 중인 동안 언제든지 다음 명령을 실행합니다.connect https://localhost:{PORT}
새로 사용 가능한
Pizza
엔드포인트를 보려면 다음 명령을 실행합니다.ls
앞의 명령은 연결된 엔드포인트에서 사용할 수 있는 모든 API를 검색합니다. 다음 코드가 표시되어야 합니다.
https://localhost:{PORT}/> ls . [] Pizza [GET] WeatherForecast [GET]
다음 명령을 실행하여
Pizza
엔드포인트로 이동합니다.cd Pizza
앞의 명령은
Pizza
엔드포인트에 대해 사용 가능한 API의 출력을 보여줍니다.https://localhost:{PORT}/> cd Pizza /Pizza [GET]
다음 명령을 사용하여
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 } ]
단일 피자를 쿼리하려면 다른
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 }
또한 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" }
Visual Studio Code의 드롭다운 목록의
dotnet
터미널로 돌아가서 키보드에서 CTRL+C를 선택하여 웹 API를 종료합니다.
이제 GET
동사 구현을 완료했습니다. 다음 단원에서는 피자 데이터에 대한 CRUD 작업을 지원하기 위해 PizzaController
에 더 많은 작업을 추가할 수 있습니다.