ASP.NET Core로 웹 API 만들기 - 튜토리얼

해질녘·2022년 1월 24일
0

닷넷 (.NET)

목록 보기
2/12

ASP.NET Core로 웹 API 만들기

이 게시물은 Tutorial: Create a web API with ASP.NET Core | Microsoft Docs 의 튜토리얼을 공부하며 작성한 발췌 번역입니다.

웹 프로젝트 생성

모델 클래스 추가

데이터베이스 컨텍스트 추가

TodoContext 데이터베이스 컨텍스트 추가

데이터베이스 컨텍스트 등록

컨트롤러 스캐폴드

  • 스캐폴딩에 필요한 NuGet 패키지 추가

  • 스캐폴딩 엔진 설치

  • scaffold

PostTodoItem create 메소드 변경

Controller/TodoItemsController.cs 수정

[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
{
    _context.TodoItems.Add(todoItem);
    await _context.SaveChangesAsync();

    //return CreatedAtAction("GetTodoItem", new { id = todoItem.Id }, todoItem);
    return CreatedAtAction(nameof(GetTodoItem), new { id = todoItem.Id }, todoItem);
}
  • [HttpPost] 애트리뷰트가 붙은 HTTP POST 메소드

  • HTTP 리퀘스트의 body에서 to-do item의 값을 가져옴.

CreatedAtAction 메소드

  • 성공했을 경우 HTTP 201 status code 

    • HTTP 201은 HTTP POST 메소드에 대한 표준 응답.
  • 응답에 Location 헤더를 붙임. 그 헤더는 새롭게 만들어진 to-do item의 URI를 지정함.

    • URI란? 하나의 리소스를 가리키는 문자열. 가장 흔한 URI는 URL이다.
  • 하드코딩을 피하기 위해 "GetTodoItem"에서 nameof키워드를 사용하는 것으로 바꿈.

http-repl 설치

웹 API를 테스트하기 위해 툴을 설치한다.

dotnet tool install -g Microsoft.dotnet-httprepl

PostTodoItem 테스트

테스트

로컬 헤더 URI 테스트

방금 post에서 입력한 정보가 1이 되어서 get으로 가져와진다.

GET 메소드 테스트

GET 엔드포인트는 2가지가 구현되어있다.

  • GET /api/todoitems
  • GET /api/todoitems/{id}

두번째꺼는 앞서 시험해봄. 첫번째껄 해보자

전체 json 목록이 출력된다.

이 앱은 현재 메모리를 데이터베이스로 삼고 있음. 앱이 중단되고 다시 시작되면 앞서 POST로 저장해둔 데이터가 사라진다.

Routing과 URL 경로

Controller/TodoItemsController.cs 수정

[Route("api/[controller]")]
[ApiController]
public class TodoItemsController : ControllerBase
  • [controller] 부분은 관례상 컨트롤러 클래스의 이름으로 지정한다. 이대 컨트롤러라는 문자열은 뺀다. 이 앱의 경우 이름은 "TodoItems"가 된다.

    • ASP.NET Core의 라우팅은 case insensitive: 대소문자 구분 x
  • If the [Http![G]()et] attribute has a route template (for example, [HttpGet("products")]), append that to the path. This sample doesn't use a template.

리턴값

GetTodoItems and GetTodoItem 메소드의 리턴값 자료형은 ActionResult<T> 형이다.

ASP.NET Core는 자동으로 개체를 JSON으로 직렬화(시리얼라이즈)하고, JSON을 응답하는 메시지 body에 쓴다.

이 반환 자료형에 대한 응답 코드는 200 OK. 처리되지않은 오류의 경우 5xx 코드가 된다.

ActionResult반환 유형은 광범위한 HTTP 상태 코드를 나타낼 수 있습니다. 예를 들어, GetTodoItem두 가지 다른 상태 값을 반환할 수 있습니다.

  • 요청된 ID와 일치하는 항목이 없으면 메서드는 404 상태 NotFound 오류 코드를 반환합니다 .
  • 그렇지 않으면 메서드는 JSON 응답 본문과 함께 200을 반환합니다. itemHTTP 200 응답 으로 결과를 반환 합니다.

PutTodoItem 메소드

HTTP put 메소드를 살펴보자.

[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
{
    if (id != todoItem.Id)
    {
        return BadRequest();
    }

    _context.Entry(todoItem).State = EntityState.Modified;

    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!TodoItemExists(id))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }

    return NoContent();
}

앞서 본 POST와 유사하다. 정상 작동 시 응답은 204 (No Content)이다.

HTTP 세부사항에 따라, PUT 요청은 변경 부분만 작게 하는 게 아니고 전체를 변경하도록 요구한다. 부분적 업데이트는 HTTP PATCH를 사용함.

뒤에서 테스트할 때 에러가 발생하면 GET을 통해 현재 데이터베이스에 아이템이 들어가 있는 지 확인하자.

DELETE 테스트

생략

Over-Posting 방지

현재 샘플 앱은 전체 TodoItem 오브젝트를 보여준다. 프로덕션의 앱은 보통 입력으로 들어오는 데이터와 모델의 일부로 보여주는 데이터를 제한한다. 몇가지 이유가 있는데, 보안이 가장 큰 이유이다. 모델의 일부는 주로 DTO (Data Transfer Object 데이터 전송 모델)나 input model, view model이라고 부른다. 이 지면에서는 DTO라고 부른다.

DTO는 이럴 때 쓰인다.

  • 오버포스팅 방지

  • 클라이언트에 보여주고 싶지 않은 property를 숨길 때

  • payload 사이즈를 줄이기 위해 property 생략 시

  • nested object가 포함된 object graph를 flatten할 때. flattened 된 object graph가 클라이언트에게 더 편리할 수 있다.

DTO 코드 변경

튜토리얼대로 코드를 변경한다.

secret 필드를 POST, GET 할 수 있는지 확인한다.

post -h Content-Type=application/json -c "{"name":"walk dog","isComplete":true, "Secret":"oh"}

결과는 아래와 같다.

HTTP/1.1 400 Bad Request
Content-Type: application/problem+json; charset=utf-8
Date: Thu, 02 Dec 2021 08:02:04 GMT
Server: Kestrel
Transfer-Encoding: chunked

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "00-7eda8bec404c05b9f14b90096c3b4d6f-94d2def71d17f9e0-00",
  "errors": {
    "$": [
      "The JSON value could not be converted to TodoApi.Models.TodoItemDTO. Path: $ | LineNumber: 0 | BytePositionInLine: 3."
    ],
    "todoItemDTO": [
      "The todoItemDTO field is required."
    ]
  }
}

실패!

이렇게 웹 API 만들기가 끝났다.

더 공부할 것은 이것들이 있다.

JavaScript로 웹 API 호출

자습서: JavaScript를 사용하여 ASP.NET Core 웹 API 호출을 참조하세요 .

웹 API에 인증 지원 추가

ASP.NET Core ID는 ASP.NET Core 웹앱에 UI(사용자 인터페이스) 로그인 기능을 추가합니다. 웹 API 및 SPA를 보호하려면 다음 중 하나를 사용하십시오.

IdentityServer4는 ASP.NET Core용 OpenID Connect 및 OAuth 2.0 프레임워크입니다. IdentityServer4는 다음 보안 기능을 활성화합니다.

  • 서비스로서의 인증(AaaS)
  • 여러 애플리케이션 유형에 대한 SSO(Single Sign-On/Off)
  • API에 대한 액세스 제어
  • 페더레이션 게이트웨이

자세한 내용은 IdentityServer4 시작을 참조하십시오 .

profile
해질녘 | 백엔드 공부 중

0개의 댓글