Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add spectral rules #20 #229

Merged
merged 5 commits into from
Aug 19, 2024
Merged

Conversation

tae0y
Copy link
Contributor

@tae0y tae0y commented Aug 18, 2024

related to #20, #21, #221
필수 필드를 지정하고, 해당 필드가 없을 경우 에러를 발생시키도록 수정

spectral openapi 기본 룰셋을 확장해서
현재 기준으로 weatherforecast, chat/completions에 지정된 필드들을 필수값으로 지정해서
없을 경우에는 error를 발생시키도록 해보았습니다~
(세부내용은 .spectral.yaml 각주에 기재해두었습니다!)

ruleset 테스트코드

# .NET 프로젝트를 백그라운드에서 실행
dotnet run --project src/AzureOpenAIProxy.AppHost &

# .NET 프로젝트의 PID를 저장
DOTNET_PID=$!

# .NET 프로젝트가 완전히 기동될 때까지 대기 (필요에 따라 조정)
sleep 10

# Swagger 파일 다운로드
rm -f swagger.json
curl https://localhost:7001/swagger/v1.0.0/swagger.json -O

# .NET 프로젝트 종료
kill $DOTNET_PID

# Spectral로 린트 수행
spectral lint swagger.json

ruleset 테스트방법

  • API 버전 규칙 : v로 시작하고 숫자와 점으로 이루어져야 함
//----------------------------------------------------------------------
// src/AzureOpenAIProxy.ApiApp/Extensions/ServiceCollectionExtensions.cs
//----------------------------------------------------------------------
// 수정전
var info = new OpenApiInfo()
{
    Version = Constants.Version, //"v1.0.0"

//----------------------------------------------------------------------
// 수정후 error
var info = new OpenApiInfo()
{
    Version = "1.0.0",
  • 모든 엔드포인트는 tags를 포함해야 함
//----------------------------------------------------------------------
// src/AzureOpenAIProxy.ApiApp/Endpoints/WeatherForecastEndpoint.cs
//----------------------------------------------------------------------
// 수정전
var builder = app.MapGet(EndpointUrls.WeatherForecast, () => {
            //( 생략 ... )
        })
        .WithTags("weather")

//----------------------------------------------------------------------
// 수정후 warn - tags는 암시적으로 생성됨, 
var builder = app.MapGet(EndpointUrls.WeatherForecast, () => {
            //( 생략 ... )
        })
        //.WithTags("weather")

//----------------------------------------------------------------------
// error - swagger.json를 직접 수정하면 발생
  • 모든 엔드포인트는 operationId를 포함해야 함 (.WithName 으로 지정)
//----------------------------------------------------------------------
// src/AzureOpenAIProxy.ApiApp/Endpoints/WeatherForecastEndpoint.cs
//----------------------------------------------------------------------
// 수정전
var builder = app.MapGet(EndpointUrls.WeatherForecast, () => {
            //( 생략 ... )
        })
        .WithName("GetWeatherForecast")

//----------------------------------------------------------------------
// 수정후 error
var builder = app.MapGet(EndpointUrls.WeatherForecast, () => {
            //( 생략 ... )
        })
        //.WithName("GetWeatherForecast")
  • 모든 엔드포인트는 summary와 description을 포함해야 함
//----------------------------------------------------------------------
// src/AzureOpenAIProxy.ApiApp/Endpoints/WeatherForecastEndpoint.cs
//----------------------------------------------------------------------
// 수정전
var builder = app.MapGet(EndpointUrls.WeatherForecast, () =>
            //( 생략 ... )
        })
        .WithOpenApi(operation =>
        {
            operation.Summary = "Get weather forecast";
            operation.Description = "Gets the weather forecast";

            return operation;
        });

//----------------------------------------------------------------------
// 수정후 error
var builder = app.MapGet(EndpointUrls.WeatherForecast, () =>
            //( 생략 ... )
        })
        .WithOpenApi(operation =>
        {
            //operation.Summary = "Get weather forecast";
            //operation.Description = "Gets the weather forecast";

            return operation;
        });
  • 응답이 정의되어 있어야함
//----------------------------------------------------------------------
// src/AzureOpenAIProxy.ApiApp/Endpoints/WeatherForecastEndpoint.cs
//----------------------------------------------------------------------
// 수정전
var builder = app.MapGet(EndpointUrls.WeatherForecast, () =>
            //( 생략 ... )
        })
        .Produces<WeatherForecast>(statusCode: StatusCodes.Status200OK, contentType: "application/json")
        .Produces(statusCode: StatusCodes.Status401Unauthorized)
        .Produces<string>(statusCode: StatusCodes.Status500InternalServerError, contentType: "text/plain")

//----------------------------------------------------------------------
// 수정후 - response를 아무것도 정의하지 않으면 200 OK가 암시적으로 생성. error를 발생시키지 않음.
var builder = app.MapGet(EndpointUrls.WeatherForecast, () =>
            //( 생략 ... )
        })
        //.Produces<WeatherForecast>(statusCode: StatusCodes.Status200OK, contentType: "application/json")
        //.Produces(statusCode: StatusCodes.Status401Unauthorized)
        //.Produces<string>(statusCode: StatusCodes.Status500InternalServerError, contentType: "text/plain")
  • 응답 코드 규칙 : 200, 401, 500 응답 코드가 모두 있어야 함
//----------------------------------------------------------------------
// src/AzureOpenAIProxy.ApiApp/Endpoints/WeatherForecastEndpoint.cs
//----------------------------------------------------------------------
// 수정전
var builder = app.MapGet(EndpointUrls.WeatherForecast, () =>
            //( 생략 ... )
        })
        .Produces<WeatherForecast>(statusCode: StatusCodes.Status200OK, contentType: "application/json")
        .Produces(statusCode: StatusCodes.Status401Unauthorized)
        .Produces<string>(statusCode: StatusCodes.Status500InternalServerError, contentType: "text/plain")

//----------------------------------------------------------------------
// 수정후 error
var builder = app.MapGet(EndpointUrls.WeatherForecast, () =>
            //( 생략 ... )
        })
        .Produces<WeatherForecast>(statusCode: StatusCodes.Status200OK, contentType: "application/json")
        //.Produces(statusCode: StatusCodes.Status401Unauthorized)
        //.Produces<string>(statusCode: StatusCodes.Status500InternalServerError, contentType: "text/plain")
  • 401을 제외한 모든 응답 코드는 content를 포함해야함
//----------------------------------------------------------------------
// src/AzureOpenAIProxy.ApiApp/Endpoints/WeatherForecastEndpoint.cs
//----------------------------------------------------------------------
// 수정전
var builder = app.MapGet(EndpointUrls.WeatherForecast, () =>
            //( 생략 ... )
        })
        .Produces<WeatherForecast>(statusCode: StatusCodes.Status200OK, contentType: "application/json")
        .Produces(statusCode: StatusCodes.Status401Unauthorized)
        .Produces<string>(statusCode: StatusCodes.Status500InternalServerError, contentType: "text/plain")

//----------------------------------------------------------------------
// 수정후 error
var builder = app.MapGet(EndpointUrls.WeatherForecast, () =>
            //( 생략 ... )
        })
        //.Produces<WeatherForecast>(statusCode: StatusCodes.Status200OK, contentType: "application/json")
        .Produces(statusCode: StatusCodes.Status401Unauthorized) // content가 없는데 오류가 나지 않음
        .Produces(statusCode: StatusCodes.Status500InternalServerError) // content가 없어서 오류가 발생함

Copy link
Contributor

@justinyoo justinyoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋습니다! 이 커스텀 룰셋을 로컬에서 테스트해 보려면 각 규칙별로 어떻게 해야 하는지를 PR 본문에 적어주시면 좋겠습니다.

@justinyoo justinyoo force-pushed the main branch 2 times, most recently from 73d2532 to 9a6f853 Compare August 18, 2024 08:26
tae0y added 3 commits August 18, 2024 18:53
related to aliencube#20, aliencube#21
필수 필드를 지정하고, 해당 필드가 없을 경우 에러를 발생시키도록 수정
- response 하위 responsecode들은 content를 포함
- 다만, 401 코드는 content를 포함하지 않아도 되게끔 수정
@tae0y tae0y force-pushed the feature/20-openapi-doc-review branch from 8aac8e2 to 0e9edfd Compare August 18, 2024 09:53
- path parameters 커스텀 검사규칙 삭제
- 내장된 spectral(path-params)를 대신 사용함
Copy link
Contributor

@justinyoo justinyoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

몇가지 불필요한 규칙만 삭제하면 될 듯 싶습니다.

불필요한 규칙 삭제
- Post RequesstBody는 암시적으로 생성됨, 규칙제거
- Get Parameters는 spectral 내장규칙사용, 불필요 각주제거
- responsecode별 description은 암시적으로 생성됨, 규칙제거
Copy link

Test Results

✔️ Tests 35 / 35 - passed in 17.5s
🔍 click here for more details

✏️ updated for commit f9791d4

Copy link

Test Results

Tests

📋 Total ✔️ Passed ❌ Failed ⚠️ Skipped
35 35 0 0

Copy link
Contributor

@justinyoo justinyoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM @tae0y 수고하셨습니다!

@justinyoo justinyoo merged commit 642ad73 into aliencube:main Aug 19, 2024
1 check passed
@tae0y tae0y deleted the feature/20-openapi-doc-review branch August 19, 2024 12:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Backend API] Review current OpenAPI doc for linting
2 participants