ASP.NET Core NativeAOT 트라이

aspnetcore nativeaot를 한번 만들어 봤는데 애초에 입문자이기도 하지만 몰랐던 기능이 많이 생겼네요. 아래 내용은 nativeaot랑 무관하게 aspnetcore에 대해서 몰랐던 기능을 적어 놓은 것입니다.

OpenAPI

OpenAPI 라는 게 생겨서 SwaggerUI를 사용하지 않아도 API Document를 볼 수 있습니다. 물론 이쁘지는 않습니다.

SwaggerUI처럼 링크로 접근하면 위와 같은 식으로 나옵니다.
App을 Build하기 전에

builder.Services.AddOpenApi("api_index_document");

이거 한번, Build 이후에

if (app.Environment.IsDevelopment())
{
    app.MapOpenApi().CacheOutput();
}

이렇게하면 끝이네요. 이건 SwaggerUI랑 똑같지만…

위 링크에 가면 API 문서의 이름을 지정하고, Endpoints를 어디로 잡을 지 설정할 수 있습니다.

.http 파일

프로젝트를 생성하니까

image

이런 파일이 생겨서 보니까 이 파일에 Test목적의 Endpoints를 적어놓으면 Postman, curl 같은 게 없이도 간단하게 버튼 눌러서 확인해볼 수 있었습니다.

5개의 좋아요

Json Response

Json 응답에 대해서 처리가 조금 달랐습니다.

기존 aspnetcore

var gameDataResponse = await HttpClient.GetAsync(uriBuilder.Uri);
gameDataResponse.EnsureSuccessStatusCode();
var realmindex = await gameDataResponse.Content.ReadFromJsonAsync<ResRealmIndex>();

NativeAOT

아래와 같이 변경해야했습니다.

var gameDataResponse = await HttpClient.GetAsync(uriBuilder.Uri);
gameDataResponse.EnsureSuccessStatusCode();
var realmindex_str = await gameDataResponse.Content.ReadAsStringAsync();
var realmindex = JsonSerializer.Deserialize(realmindex_str, SourceGenerationContext.Default.ResRealmIndex);
namespace VincentBattleNetApiServer.Core;

using VincentBattleNetApiServer.Core.DTOs.Res;

[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(BattlenetAccessToken))]
[JsonSerializable(typeof(ResRealm))]
[JsonSerializable(typeof(ResRealmIndex))]
public partial class SourceGenerationContext : JsonSerializerContext
{
}

이런 식으로 System.Text.Json을 이용해서 Source Generator를 이용해서 처리해야 했습니다.

1개의 좋아요

.NET 8부터 aspnetcore 기본 포트가 8080으로 변경됨.

아무것도 안했는데 포트가 알아서 8080으로 잡히길래 검색해보니 이런 게 있었습니다.

1개의 좋아요

OpenApi 는 말 그대로 공개 api 서비스에 적절합니다.

그러므로, 공개 Api 를 작성하는 경우가 아니라면, 배포 코드에서 지워야 합니다.

if (builder.Environment.IsDevelopment())
{
    builder.Services.AddOpenApi();
}

// ...
var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
};
// ...

그럼에도 개발자에게 유용한 부분이 있습니다.

테스팅

Api의 동작을 테스트 할 때, PostMan 과 같은 전문 클라이언트를 사용할 수도 있고, .http 파일도 사용할 수 있는데, Swagger Ui 도구를 사용하는 방식이 가장 간편하다고 할 수 있습니다.

.Net 8.0 까지는 Swashbuckle 이 공식 Swagger Ui 도구였는데, .Net 9.0 부터는 기존의 Swashbuckle 대신, SwaggerUI 패키지를 사용하면 됩니다.
이 패키지 뿐만 아니라, 다른 UI 도구도 사용할 수 있습니다.

클라이언트 생성

OpenApi 문서의 다른 효용은 클라이언트를 표준화할 수 있다는 점입니다.

닷넷에서는 NSwag 를 사용하면, OpenApi 문서를 바탕으로 Api 에 접근할 수 있는 서비스 객체와 관련 데이터 모델을 자동으로 생성할 수 있습니다.
이는 EF Core 의 Db-First 접근법과 유사한 방식입니다.

nodejs 서버든 kestrel 서버든, openapi 문서만 제공해주면, 위 도구로 닷넷 또는 다른 언어의 클라이언트 객체를 만들 수 있는 것이죠.

직접 시도해 봤는데, 시스템의 모든 앱이 닷넷으로 작성된 경우에는, 생성된 객체들이 뭔가 불편하지만, 다른 언어로 작성된 api 에 접근하는 클라이언트를 닷넷으로 작성하는 경우라면, 코드량을 상당히 많이 줄여주는 이점이 있습니다.

사견으로는, 비공개 api 를 작성하는 경우라도, open api 문서를 별도의 파일로 생성해두는 편이 나중에 도움이 될 것 같습니다.

시스템이 성공적이면, 누군가는 api 에 접근을 원할 것이고, 그 경우에 만들어 둔 open api 문서를 제공하면, 클라이언트를 작성하는 측의 업무가 많이 효율적이게 되고, 그 만큼 지원할 거리도 적어지니까요.

4개의 좋아요

openapi는 .net 9에서 또 바뀌죠

2개의 좋아요

맞습니다. 그래서 OpenAPI 자체는 예전 닷넷 프레임워크 초창기 때 많이 통용되던 WSDL 기반 XML 웹 서비스의 현대적 해석으로 볼 수 있을 것 같습니다. (물론 그 때는 Java 측 WSDL 구현과 닷넷 측 WSDL 구현이 달라서 호환성이 좋지 않았었습니다.)

Google의 경우에는 본인들이 제공하는 서비스의 OpenAPI 스펙을 정교하게 설계해서 각종 언어별 SDK 라이브러리 제작 자체를 자동화하는 것으로도 알고 있습니다. OpenAPI에 투자할 수 있는 여력이나 여건이 충분하다면 꽤 흥미로운 접근 방식일 수 있겠다고 생각했습니다. :smiley:

4개의 좋아요