ASP를 사용합니다.NET 코어에서 간단한 JSON API로 라우팅하는 코드

24906 단어 aspnetcoredotnet
ASP에서 API를 작성해야 하는 경우NET Core는 전통적으로 사용되어야 합니다ASP.NET Core MVC.비록 매우 성숙하고 기능이 완비되어 있지만, 그것도 ASP의 핵심 원칙에 위배된다.NET Core, 다른 ASP 와 다릅니다.NET 핵심 제품따라서 프레임의 많은 기능을 사용하지 않더라도 전체 프레임을 사용해야 한다.대부분의 경우 다른 곳에서 논리를 실행하려면 상하문(HTTP의 CRUD 작업)을 실행하는 것이 좋습니다.
컨트롤러와 동작 방법을 사용하는 함정도 포함되지 않는다.MVC 모드는 우리가 다른 개발자들에게 마른 컨트롤러의 중요성을 홍보하는 것처럼 의존성과 팽창성을 가진 컨트롤러를 남용하게 할 것이다.마이크로소프트는 이 점을 매우 잘 안다.이번 주에는 ASP에서NET가 일어섰을 때, 프로그래머인 데이비드 Fowler는 Houdini 프로젝트가 MVC의 API를 더욱 경량급과 고성능으로 바꾸도록 돕는 노력이라고 언급했다. (본고 말미에 이에 대해 상세하게 소개할 것이다.)
저희가 지금 an alternative명이'코드 노선'이라고 있어요.이제 ASP를 작성할 수 있습니다.NET 코어 API - 라우트를 중간부품에 연결합니다.따라서, 코드는 요청을 읽고, 응답을 작성할 수 있으며, 복잡한 프레임워크와 고급 설정에 의존하지 않습니다.간단한 JSON API에서 파이프에 대한 묘한 경험입니다.
명확하게 지적해야 할 것은 Microsoft will be the first to tell you this 모델 귀속, 내용 협상, 고급 검증 등이 필요 없는 기본 JSON API에 적용된다는 것이다.이러한 장면의 경우 ASPNET Core MVC는 항상 사용자에게 제공됩니다.
다행히 나는 방금 MVCwrote a sample API에서 look at the HttpRepl tool로 업그레이드되었다.이것은 루트를 코드로 바꾸고 나의 경험을 보여주는 좋은 프로젝트이다.
이 글은 다음과 같은 내용을 포함하고 있다.
  • How does route-to-code work?
  • A quick tour of the route-to-code MVC project

  • Migrate our APIs from MVC to route-to-code
  • The “get all items” endpoint
  • The “get by id” endpoint
  • The post endpoint
  • The delete endpoint
  • The path forward
  • Wrap up
  • 루트 코드는 어떻게 작동합니까?


    route to code에서 항목의 Startup.cs 파일에 API를 지정합니다.이 파일 (or even in another one 에서 UseEndpoints 에서 프로그램 요청 파이프의 루트와 API 논리를 정의합니다.
    이걸 사용하려면, ASP.NET Core는 다음과 같은 3가지 접근 방식을 제공합니다.

  • ReadFromJsonAsync - 요청에서 JSON을 읽고 지정된 유형으로 반서열화

  • WriteAsJsonAsync - 값을 JSON으로 응답체에 쓰고 응답 유형을 application/json로 설정합니다.

  • HasJsonContentType - 검사Content-Type 머리에 JSON
  • 의 브리 방법
    코드 라우트는 기본 API에만 적용되므로 현재 지원되지 않습니다.
  • 모델 귀속 또는 검증
  • OpenAPI
  • 구조 함수 의존항 주입
  • 콘텐츠 협상
  • 이 문제를 해결할 수 있는 여러 가지 방법이 있지만, 중복된 코드를 대량으로 작성한 것을 발견하면, 이것은 ASP를 더욱 잘 활용할 수 있다는 좋은 징조입니다.NET 핵심 MVC.

    코딩된 MVC 프로젝트의 빠른 탐색


    나는 코드 프로젝트 노선out on GitHub이 있다.나는 모든 설정 코드를 통독하지는 않지만, 더 많은 탐색을 원한다면, 중요한 부분에만 연결할 것입니다.
    예시 프로그램에서 나는 메모리 실체 프레임워크 데이터베이스에 연결했다.내가 사용한 a SampleContext class은 실체 구조의 핵심DbContext을 사용했다.나는 a SeedData class C#9 기록을 사용하여 데이터베이스를 채운다a model.
    ConfigureServices middleware in Startup.cs 에서 메모리에 있는 데이터베이스를 용기에 추가한 다음flip on the switch in Program.cs .

    MVC에서 라우팅에서 코드로 API 마이그레이션


    본고에서, 나는 나의 MVC 컨트롤러의 GET, GET (by id),post,DELETE 방법을 소개하고, 그것들을 어떻게 코드 루트로 옮기는지 이해할 것이다.
    우리가 이렇게 하기 전에 먼저 간단한 설명을 하나 하자.MVC에서, 나는 구조 함수 주입을 사용하여 나의 SampleContext 데이터베이스에 접근했다.context는route to code에서 자주 사용하는 용어이기 때문에route to code에서 repository라고 명명할 것입니다.
    한 마디로 하면 다음은 구조 함수가 ASP에 주입된 외관이다.NET 핵심 MVC 프로젝트:
    using HttpReplApi.Data;
    using Microsoft.AspNetCore.Mvc;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using HttpReplApi.ApiModels;
    
    namespace HttpReplApi.Controllers
    {
        [Produces("application/json")]
        [Route("[controller]")]
        public class BandsController : ControllerBase
        {
            private readonly SampleContext _context;
    
            public BandsController(SampleContext context)
            {
                _context = context;
            }
    
            // action methods
    
        }
    }
    
    다음 몇 절에서, 나는 모든 단점을 소개하고, 루트를 코드로 전환하는 방법을 이해할 것이다.

    모든 항목 가져오기 끝점


    "get all"단점에 대해 MVC 조작 방법은 매우 자명하다.나는 이미 상하문에 주입했기 때문에, 데이터는 내가 조회할 수 있도록 준비가 되어 있기 때문에, 나는 그것을 얻기만 하면 된다.
    [HttpGet]
    public ActionResult<IEnumerable<Band>> Get() =>
        _context.Bands.ToList();
    
    앞에서 설명한 대로 코드로 라우팅되는 모든 끝점 라우팅과 논리는 app.UseEndpoints에 있습니다.
    app.UseEndpoints(endpoints =>
    {
        // endpoints here
    };
    
    이제 우리는 (914)와 (454)의 단점을 정의할 수 있다.이 코드를 보아라, 우리는 뒤에서 토론할 것이다.
    endpoints.MapGet("/bands", async context =>
    {
        var repository = context.RequestServices.GetService<SampleContext>();
        var bands = repository.Bands.ToListAsync();
        await context.Response.WriteAsJsonAsync(bands);
    });
    
    라우팅 템플릿이 있는 HTTP GET 끝점을 요청하고 있습니다.이 예에서 MapGet/bands이다. 여기서 나는 서비스를 요청하고 검색 문자열을 얻으며 JSON을 읽고 쓸 수 있다.
    나는 코드 루트를 사용하기 위해 구조 함수 기반 의존 주입 (DI) 을 사용할 수 없다.서비스에 주입할 프레임워크가 없기 때문에, 우리는 수동으로 이 서비스들을 해석해야 한다.그래서 context에서 나는 HttpContext로 나를 해결할 수 있다HttpContext.RequestServices.순간 또는 역할 영역의 생존 기간을 가진 모든 서비스에 대해 귀하가 사용해야 합니다GetService.Logger와 같은 단일 역할 영역이 있는 서비스의 경우 서비스 제공업체에서 이를 선언할 수 있습니다.이 경우 다른 요청에서 사용할 수 있습니다.그러나 우리의 예에서 우리는 모든 단점 중복SampleContext 서비스에 대해 이것이 저항력이라는 것을 발견해야 한다.
    마지막으로 저는 RequestServices 방법으로 JSON의 형식으로 집합repository을 보낼 것입니다.

    "id로 가져오기" 단점


    가장 일반적인 사용 사례Bands는 무엇입니까?다음은 MVC 디렉터에서 구현되는 방법입니다.
    [HttpGet("{id}")]
    public async Task<ActionResult<Band>> GetById(int id)
    {
        var band = await _context.Bands.FindAsync(id);
    
        if (band is null)
        {
            return NotFound();
        }
    
        return band;
    }
    
    코드를 작성하는 동안 다음과 같이 표시됩니다.
    endpoints.MapGet("/bands/{id}", async context =>
    {
        var repository = context.RequestServices.GetService<SampleContext>();
        var id = context.Request.RouteValues["id"];
        var band = await repository.Bands.FindAsync(Convert.ToInt32(id));
    
        if (band is null)
        {
            context.Response.StatusCode = StatusCodes.Status404NotFound;
            return;
        }
        await context.Response.WriteAsJsonAsync(band);
    });
    
    이 경로는 해당 경로에서 전달된 Response.WriteAsJsonAsync와 일치합니다.방문id을 통해 얻을 필요가 있습니다.문서에서 언급하지 않은 것은 모델이 연결되어 있지 않기 때문에 id 문자열을 정수로 수동으로 변환해야 한다는 것이다.내가 이 점을 이해한 후에, 나는 상하문에서 Request.RouteValues 호출하여 그것을 검증한 후에 id 방법에서 그것을 작성할 수 있다.

    종착역


    이곳은 흥미로운 곳입니다. 우리는 어떻게 모델의 귀속이나 검증이 없는 상황에서 발표합니까?
    다음은 기존 컨트롤러의 ASP 작동 방식입니다.NET 핵심 MVC.
    [HttpPost]
    public async Task<ActionResult<Band>> Create(Band band)
    {
        _context.Bands.Add(band);
        await _context.SaveChangesAsync();
    
        return CreatedAtAction(nameof(GetById), new { id = band.Id }, band);
    }
    
    코드를 작성하는 동안 다음과 같은 내용을 썼습니다.
    endpoints.MapPost("/bands", async context =>
    {
        var repository = context.RequestServices.GetService<SampleContext>();
    
        if (!context.Request.HasJsonContentType())
        {
            context.Response.StatusCode = StatusCodes.Status415UnsupportedMediaType;
            return;
        }
    
        var band = await context.Request.ReadFromJsonAsync<Band>();
        await repository.SaveChangesAsync();
        await context.Response.WriteAsJsonAsync(band);
    });
    
    앞에서 보듯이 우리는 FindAsync 방법을 사용할 수 있다. 내가 JSON을 얻었는지 확인해 보자.만약 없다면, 나는 상응하는 상태 코드를 설정하고 돌아올 수 있다.
    나는 JSON이 있기 때문에 (검증이나 귀속은 없고 단지 JSON임을 검증할 뿐) 그것을 읽고 데이터베이스에 저장할 수 있다.완료 후, 나는 WriteAsJsonAsync 신기록을 전보를 보낸 사람에게 돌려주거나, 다음과 같은 조작을 수행할 수 있다.
    context.Response.StatusCode = StatusCodes.Status201Created;
    return;
    
    HasJsonContentType 200이 반환되고 200만 반환됩니다.이것은 우리가 틀이 없기 때문에 수공으로 완성해야 한다는 것을 기억해라.

    끝점 삭제


    Dell의 DELETE API는 POST와 매우 유사합니다.
    다음은 기존 MVC 디렉터에서 수행한 내용입니다.
    [HttpDelete("{id}")]
    public async Task<IActionResult> Delete(int id)
    {
        var band = await _context.Bands.FindAsync(id);
    
        if (band is null)
        {
            return NotFound();
        }
    
        _context.Bands.Remove(band);
        await _context.SaveChangesAsync();
    
        return NoContent();
    }
    
    다음은 제가 코드 노드 루트에 쓴 내용입니다.
    endpoints.MapDelete("/bands/{id}", async context =>
    {
        var repository = context.RequestServices.GetService<SampleContext>();
    
        var id = context.Request.RouteValues["id"];
        var band = await repository.Bands.FindAsync(Convert.ToInt32(id));
    
        if (band is null)
        {
            context.Response.StatusCode = StatusCodes.Status404NotFound;
            return;
        }
    
        repository.Bands.Remove(band);
        await repository.SaveChangesAsync();
        context.Response.StatusCode = StatusCodes.Status204NoContent;
        return;
    });
    
    보시다시피 이처럼 가소로운 API라도 여러 가지 요소를 고려해야 합니다.응용 프로그램에서 의존 의존 주입에 의존하면 의존 주입 문제를 해결하기 어렵다.


    하리드🎅🎄

    나는 핵심 매핑 방법이 DI를 지원하기를 바란다🥺반대로, 나는 혈거인처럼 프로그래밍을 해야 한다
    2020년 12월 3일 오후 19:11
    이것이 바로 이런 무구조 해결 방안을 사용하는 데 지불한 대가이다.결과적으로 단순성과 성능을 얻을 수 있습니다.이것은 당신이 모든 방울과 휘파람을 필요로 하는지, 아니면 코드의 경로만 필요로 하는지 결정하는 데 달려 있다.

    진로


    부인할 수 없다. 이 용례는 매우 작기 때문에 여기에 MVC에서 이런 좋은 점을 누릴 수 있다면?이것이 바로 다비드 플러의 이번 주 ASP다.테니스 단식.
    이 작업은 MVC 생산성 특성을 스택의 핵심으로 밀고 성능에 초점을 맞춘다.Fowler는 컴파일할 때 원본 코드를 사용하여 이 코드의 API를 생성하는 방법을 보여 줍니다. 이것은 전통적인 MVC 코드를 계속 작성할 수 있도록 합니다.물론 AOT가 나타날 때.NET 6는 성능과 나무 오르기 능력에 도움이 될 것입니다.

    마무리


    본 논문에서, 우리는 API 스타일 코드를 작성하는 경로와, 그리고 어떻게 하면 당신이 더욱 간단한 API를 작성하는 데 도움을 줄 수 있는지 토론하였다.우리는 컨트롤러 코드를 코드로 어떻게 옮기는지 연구했고 미래의 경로도 연구했다.

    좋은 웹페이지 즐겨찾기