-
[OCA] Azure Function OpenAPI Issue #485카테고리 없음 2023. 9. 20. 14:36
Challengers 기간이 끝나고, Masters 기간에 들어서면서 팀을 이루어 Issue를 맡아 해결해보는 과정을 진행했습니다.
1. 이슈 파악
https://github.com/Azure/azure-functions-openapi-extension/issues/485
New feature: `JsonSerializerSettings` or `NamingStrategy` to be injectable · Issue #485 · Azure/azure-functions-openapi-extens
Currently, both JsonSerializerSettings and NamingStrategy are not injectable. It should be injectable by devs.
github.com
기존에 Newtonsoft.JsonSerializer로 NamingStrategy를 Serialize해왔는데, NamingStrategy가 CamelCase로 고정되어 있었다. 따라서, ConfigurationOption에 NamingStrategy를 추가해 local.setting.json에서 값을 성정하면 Inject해서 원하는 NamingStrategy를 선택할 수 있게 해야 한다.
2. 해결 과정
1. NamingStrategy(CamelCase, PascalCase, SnakeCase, KebabCase)를 Enum으로 생성
2. IOpenAPIConfigurationOption , OpenAPIConfigurationOption, DefaultOpenAPIConfigurationOption에 NamingStrategy를 추가하고, GetNamingStrategy와 DefaultNamingStrategy를 추가
=> 여기까지 해서 local.setting.json에서 Enum타입으로 NamingStrategy를 가져올 수 있었지만, 어디에서 NamingStrategy를 주입하는지 찾지 못했었다.
계속 찾아본 결과, OpenAPIHttpTriggerContext에서 NamingStrategy의 기본 설정 값이 Newtonsoft.CamelCaseNamingStrategy로 고정되어 있는 것을 확인할 수 있었다.
// OpenApiHttpTriggerContext.cs // 기존에는 CamelCaseNamingStrategy를 직접 주입해 값을 변경할 수 없었다. public virtual NamingStrategy NamingStrategy { get; } = new CamelCaseNamingStrategy();
3. NamingStrategy = new CamelCaseNamingStrategy; 로 되어 있는 것을 get { method } 로 configOption에 있는 Enum Type의 NamingStrategy를 가져온다.
문제점 ) 이 프로그램에서는 DefaultNamingStrategy가 CamelCase이지만 Newtonsoft에서는 PascalCase를 DefaultNamingStrategy로 설정해 놓았다.
그래서, get {}을 통해서 가져올 때, switch문 혹은 CreateInstance를 사용할 때 코드의 길이가 길어지고, 추가적인 처리를 할 필요가 생겼다.
// Switch 문을 활용한 방식 public static class NamingStrategyFactory { public static NamingStrategy Create(NamingStrategyType strategyType) { switch (strategyType) { case NamingStrategyType.CamelCase: return new CamelCaseNamingStrategy(); case NamingStrategyType.PascalCase: return new DefaultNamingStrategy(); case NamingStrategyType.SnakeCase: return new SnakeCaseNamingStrategy(); case NamingStrategyType.KebabCase: return new KebabCaseNamingStrategy(); default: return new CamelCaseNamingStrategy(); } } } // CreateInstance를 활용한 방식 public virtual NamingStrategy NamingStrategy { get { string enumName = this._configOptions.OpenApiNamingStrategy.ToString(); string className = $"{enumName}NamingStrategy"; string fullClassName = $"Newtonsoft.Json.Serialization.{className}, Newtonsoft.Json"; try { Type namingStrategyType = Type.GetType(fullClassName); if (namingStrategyType != null) { namingStrategyInstance = (NamingStrategy)Activator.CreateInstance(namingStrategyType); return namingStrategyInstance; } } catch (TypeLoadException e) { Console.WriteLine("{0}: Unable to load type ", e.GetType().Name); } return new CamelCaseNamingStrategy(); } }
==> 기존에 있던 OpenApiConfigurationResolver method를 overloading해 NamingStrategy.Enum이 들어왔을 때, 각 Enum 값에 맞는 NamingStrategy를 반환하게 해결했다.
// 기존의 Resolve 메소드 public static IOpenApiConfigurationOptions Resolve(Assembly assembly) { var type = assembly.GetLoadableTypes() .SingleOrDefault(p => p.HasInterface<IOpenApiConfigurationOptions>() == true && p.IsAbstract == false && p.HasCustomAttribute<ObsoleteAttribute>() == false && p.HasCustomAttribute<OpenApiConfigurationOptionsIgnoreAttribute>() == false); if (type.IsNullOrDefault()) { return new DefaultOpenApiConfigurationOptions(); } var options = Activator.CreateInstance(type); return options as IOpenApiConfigurationOptions; } // OpenApiNamingStrategy로 overloading해서 값을 return public static NamingStrategy Resolve(OpenApiNamingStrategy strategyType) { switch (strategyType) { case OpenApiNamingStrategy.CamelCase: return new CamelCaseNamingStrategy(); case OpenApiNamingStrategy.PascalCase: return new DefaultNamingStrategy(); case OpenApiNamingStrategy.SnakeCase: return new SnakeCaseNamingStrategy(); case OpenApiNamingStrategy.KebabCase: return new KebabCaseNamingStrategy(); default: return new CamelCaseNamingStrategy(); } }
4. NamingStrategy의 경우 Integration-Test를 작성하기엔 애매하다 생각했고, 각각의 method들에 대해 unit-Test를 작성했다.
3. PR 그리고 Merge
https://github.com/Azure/azure-functions-openapi-extension/pull/613
Add : Set NamingStrategy Type by HongGeonUi · Pull Request #613 · Azure/azure-functions-openapi-extension
#485 We add new option for setting to namingstrategy. IOpenApiConfigurationOptions OpenApiConfigurationOptions DefaultApiConfiguationOptions Enum : OpenApiNamingStrategy Workers.OpenApiHttpTrigger...
github.com
PR을 올리고 내가 작성했던 부분에 있던 오타,, 를 빼고는 인정되어 PR이 Merge될 수 있었다.