[.NET]Swagger UI에 Customized Data Type 표현하기

API를 개발하면서 정의한 호출/응답 Class Model의 Properties에 별도로 Customized Data Type(Attribute)를 적용하여 사용할때가 있는데, 이런경우, Customized Data Type은 자료형이 아니기 때문에 Swagger에서 표현되지 않아, API 사용자에게 특정 Property의 상세한 스팩을 전달 하기 어렵게 된다.

이런 속성들을 나타내려면 SwaggerConfig의 Schema Filter를 사용하면 된다.

Schema Filter를 사용하면, Swagger Document Json 파일에 사용자가 정의한 Customized DataType을 추가 할 수 있게 되어 Swagger UI에서도 사용자가 정의한 Data Type이 표현 되어 진다.

Customized Data Type(Attribute)을 정의하고 Model에 적용하여 확인해보자.

1. Customized Attribute Class를 정의한다. 
(Tip, Attribute Class 정의 위에 Attribute Usage 속성을 명시적으로 정의 해주면, 사용자가 정의한 Customized Data Type(Attribute)이 의도하지 않은 형태로 사용되는 것을 예방 할 수 있다.)

    /// <summary>
    /// Customized Attribute
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
    public class CustomizedAttribute : Attribute
    {
        /// <summary>
        /// Customized Attribute
        /// </summary>
        /// <param name="DataType">Attribute Name</param>
        public CustomizedAttribute(string DataType)
        {
            DataTypeName = DataType;
        }

        /// <summary>
        /// Name of DataType
        /// </summary>
        public string DataTypeName { get; set; }
    }

2. 1번에서 정의한 Attribute를 아래와 같이 API에서 응답/호출에 사용할 Model의 Properties에 적용한다.

    /// <summary>
    /// Student Info Model
    /// </summary>
    public class StudentInfo
    {
        /// <summary>
        /// ID
        /// </summary>
        [Required]       
        public string StudentID { get; set; }

        /// <summary>
        /// Name
        /// </summary>
        [Required]
        [CustomizedAttribute("MyType")]
        public string Name { get; set; }

        /// <summary>
        /// Gender
        /// </summary>
        public string Gender { get; set; }

        /// <summary>
        /// Phone Number
        /// </summary>
        [CustomizedAttribute("MyType")]
        public string Phone { get; set; }

        /// <summary>
        /// Address
        /// </summary>
        [CustomizedAttribute("MyType")]
        public string Address { get; set; }
    }

여기까지 하면, 일단은 Model Properties에는 적용되어 시스템에는 반영 되었지만, Swagger UI에서 확인을 할 수 없다.

확인해 보기 위해서 프로젝트를 실행하면 다음과 같이 Customized Data Type을 적용한 Properties들이 일반 자료형인 string으로 표현 되는 것을 볼 수 있다.

이제 String으로 표현된 부분을 Attribute로 정의한 “MyType”으로 나오도록 Schema Filter를 설정해 보자.

1. Schema Filter로 사용할 Filter Class “ApplySchemaVendorExtensions”를 다음과 같이 추가(정의)한다.

    /// <summary>
    /// Vendor Extensions
    /// </summary>
    public class ApplySchemaVendorExtensions : ISchemaFilter
    {
        /// <summary>
        /// Get Customed Attribute Schema
        /// </summary>
        /// <param name="schema">Document Schema</param>
        /// <param name="schemaRegistry">Document Schema Repository</param>
        /// <param name="type">Model Definition</param>
        public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
        {            
            var propertyMappings = type.GetProperties()
                                   .Join(schema.properties ?? new Dictionary<string, Schema>(),
                                   x => x.Name.ToLower(), y => y.Key.ToLower(),
                                   (x, y) => new KeyValuePair<PropertyInfo, KeyValuePair<string, Schema>>(x, y)).ToList();

            foreach (var propertyMapping in propertyMappings)
            {
                var propertyInfo = propertyMapping.Key;
                var propertyNameToSchemaKvp = propertyMapping.Value;

                foreach (var attribute in propertyInfo.GetCustomAttributes())
                {
                    SetSchemaDetails(propertyNameToSchemaKvp, attribute);
                }
            }
        }

        /// <summary>
        /// Set Customized Schema Details
        /// </summary>
        /// <param name="propertyNameToSchemaKvp">Property Schema</param>
        /// <param name="propertyAttribute">Customized Attribute</param>
        private static void SetSchemaDetails(KeyValuePair<string, Schema> propertyNameToSchemaKvp, object propertyAttribute)
        {
            var schema = propertyNameToSchemaKvp.Value;

            if (propertyAttribute is CustomizedAttribute)
            {
                string dataType = ((CustomizedAttribute)propertyAttribute).DataTypeName;

                schema.type = dataType;

                schema.example = "string";
            }        
        }
    }

위 코드에서 작성한 Schema Filter에서는, Swagger에서 화면을 구성하기 위한 Swagger Document Json 파일을 생성할때, 해당 Schema Filter에서 사용자가 정의한 Customized Data Type을 Swagger Document Json파일 내용에 반영 하도록 한다. 

2. 1번에서 정의한 Schema Filter인 “ApplySchemaVendorExtensions”을 다음과 같이 SwaggerConfig에 추가 설정하여, 필터가 동작 할 수 있도록 한다.

GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
 c.SchemaFilter<ApplySchemaVendorExtensions>();
})
/*.......... 생략 ............*/

여기까지 Customized Data Type에 대한 정의 및 표현(구현)을 위한 Schema Filter 설정까지 모두 완료 되었다. 

이제, 프로젝트를 다시 실행 시켜 보면 자료형으로 표현 되었던 Properties들이 모두 Customized Data Type인 MyType이 표현 된 것을 확인 할 수 있다. 

Schema Filter 적용 전

Schema Filter 적용 후

– 유의사항 –
Swagger UI는 API 사용자에게 제공되는 스팩 문서인기 때문에, API 사용자가 어떻게 이해 할 것인가를 우선 고려 해야 한다. 위 방법을 통하면, 해당 Model Property가 특정하게 이용(처리)되는 것을 명시적으로 표현 할 수 있지만, 만약 정의한 속성 때문에 API 사용자가 모델에 사용할 Data Type이 혼동이 온다면, 필터를 적용하지 않고 일반 자료형이 표현되게 하고 Implementation Note에 별도로 작성하여 안내하는 것이 더 좋을 수 있다.   

글쓴이

thenewth

AI Research Engineer & Cloud Platform Developer

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google photo

Google의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중

This site uses Akismet to reduce spam. Learn how your comment data is processed.