Qayta ishlash sababi
Loyihamizning rivojlanish muhitida Swagger kutubxonasini mijozning xizmatlariga to'g'ridan-to'g'ri qo'llashda cheklov mavjud edi. Oddiy Spring asosidagi xizmat bo'lsa, Springfox yoki springdoc-openapi orqali Controller va DTO asosidagi API belgilashlarini avtomatik ravishda yaratish mumkin, lekin mijozning muhitida xizmatlarga bog'lanish qo'shish va ishlash vaqtida birlashtirish erkin emas edi.
Shunga qaramay, mijoz API belgilashini boshqarish uchun Swagger'dan foydalanishni xohlar edi. Xususan, hozirgi tarqatilgan API ro'yxati va batafsil request, response tuzilmasini Swagger UI'da ko'rishni xohlayotgan ehtiyojlari bor edi, eng muhimi, bir nechta rivojlantirish jamoalari tomonidan har biri ishlab chiqilgan xizmatlarning API qo'lda hujjat yozilishi va yangilanishi kechikishi bilan bog'liq VOClar yuzaga kelayotgan edi.
PoCning boshlanish nuqtasi bu cheklovni saqlab turar ekan, Swagger asosidagi hujjatlashtirish tajribasini taqdim eta olishimizni tekshirish edi. Ya'ni, har bir xizmatga Swagger kutubxonasini to'g'ridan-to'g'ri ulamasdan hammarkaziy Swagger serveri orqali tarqatilgan API belgilashlarini tekshirishga imkon beruvchi tuzilmani yaratish maqsadi edi.
Muammo aniqlanishi
Ushbu loyihaning asosi mijozning barcha rivojlantirish jamoasi bitta Swagger serveriga ulanishi va hozirgi tarqatilgan API belgilashlarini ko'rish imkoniyatini yaratish edi. Shunga ko'ra, individual xizmatlar ichida Swagger hujjatlarini ko'rsatish usulidan ko'ra, markaziy Swagger serveri bir nechta API belgilashlarini to'plab, birlashtirgan taqdimot usulini rejalashtirdik.
-
API belgilashlari tarqatilish vaqtida to'planib alohida boshqariladigan markaziy Swagger serveriga real vaqt sifatida aks ettirilishi maqsad qilindi.
-
Belgi fayli Swagger UI'da bevosita o'qilishi mumkin bo'lgan YAML formatida bo'lishi zarur edi.
-
Kelajakda har bir rivojlantirish jamoasi men taqdim etadigan Custom Annotation faqat qo'shsa ham belgi avtomatik ravishda yaratiladigan tuzilma bilan kengaytirilishi kerak edi.
PoCda ushbu maqsadni ikki bosqichga bo'lib tekshirdik. Avval API'lardan to'plangan Req / Res ma'lumotlarini Swagger YAML formatida avtomatik ravishda yaratib, alohida serverda birlashtirib taqdim etdik va keyinchalik Custom Annotation asosida API va VO dan tahlil qilib YAMLni yaratish uchun kutubxona sifatida yo'naltirishni tekshirdik.
PoC tuzilmasi haqida umumiy ma'lumot
Xizmatlar asosan uchta sohalarga bo'lingan. swagger-apis avtomatik ravishda yaratilgan API belgilash YAML fayllarini saqlaydigan tashqi saqlash joyi vazifasini bajaradi, swagger-demo esa ushbu YAML fayllarni o'qib Swagger UI'ga ko'rsatadigan Spring Boot serveridir. swagger-file-generator Java ob'ektidan asoslangan Swagger YAML faylini yaratish mumkinligini tekshirib, kutubxona sifatida har bir rivojlantirish jamoasiga taqdim etish uchun loyiha hisoblanadi.
|
Papka |
Roli |
Tavsifi |
|---|---|---|
|
swagger-apis |
Tavsif fayllari saqlash joyi |
API bo'yicha swagger.yaml fayllarini saqlash uchun tashqi katalog. |
|
swagger-demo |
Swagger server |
Spring Boot va Springfox yordamida bir necha YAML fayllarni Swagger UI ga ro'yxatga oladi. |
|
swagger-file-generator |
YAML yaratish tajribasi |
Java obyekt modelini YAML matniga aylantirib va faylga saqlaydi. |
Ushbu tuzilmaning afzalligi shundaki, Swagger UI taqdim etish vazifasi va API tavsifini yaratish vazifasini ajratish mumkin. Xizmat kodi tavsif yaratishga qaratilgan, markaziy Swagger server esa YAML fayli asosida UI ni taqdim etadi.
Markaziy Swagger serverni sozlash
swagger-demo loyihasi Spring Boot asosidagi Swagger serverdir. Ushbu server o'z API'ini hujjatlashtirmaydi, balki tashqi, ya'ni har bir dasturchi jamoasi tomonidan taqdim etilgan bir nechta Swagger YAML fayllarni Swagger UI'da tanlanadigan resurs sifatida ro'yxatga oladi. Mijoz tashkilotidagi har bir dasturchi jamoasi ushbu serverning Swagger UI'siga kirib, joriy tarqatilgan API tavsiflarini ko'rish imkoniyatiga ega.
Asosiy amalga oshirish SwaggerResourcesProvider'ni qayta belgilashdan iborat. Springfox tomonidan taqdim etilgan Swagger resurslari ro'yxatini to'liq ishlatmasdan, tashqi katalogdan YAML fayllarini o'qib, to'g'ridan-to'g'ri SwaggerResource ro'yxatini tuzadi.
@Primary
@Bean
public SwaggerResourcesProvider swaggerResourcesProvider(
InMemorySwaggerResourcesProvider defaultResourcesProvider
) {
return () -> {
List<SwaggerResource> resources = new ArrayList<>();
List<File> innerFiles = createFilesFromExternalDir();
innerFiles.forEach(file -> {
String path = "/" + file.getParentFile().getParentFile().getName()
+ "/" + file.getParentFile().getName()
+ "/" + file.getName();
String title = Files.readAllLines(file.toPath()).stream()
.filter(f -> f.contains("title"))
.findFirst()
.map(m -> m.split(":")[1].split("\"")[1])
.orElseGet(() -> "No Title");
resources.add(loadResource(path, title));
});
return resources;
};
}
Yuqoridagi kodning asosiy nuqtasi Swagger UI'da ko'rsatiladigan resurslarni dinamik ravishda tuzishdir. Har bir YAML faylning yo'li Spring Boot statik resurs yo'li sifatida yaratiladi va YAML ichidagi title qiymati Swagger UI ochiladigan ro'yxatida ko'rsatiladigan nom sifatida ishlatiladi.
Ushbu usul bilan serverni tuzishda har bir dasturchi jamoasi Swagger UI serverini alohida boshqarishga ehtiyoj sezmaydi. Faqat markaziy Swagger serverini tarqatish kifoya, har bir API tavsifi YAML fayl birligi bo'yicha qo'shiladi va Swagger UI'da tanlanadigan element sifatida ko'rsatiladi.
Tashqi YAML yig‘ish va statik resurslarni aks ettirish
swagger-demo rootdagi swagger-apis direktoriyasini tashqi spetsifikatsiya saqlash joyi sifatida ishlatadi. Server ishga tushganda ../swagger-apis/ ostidagi API bo‘yicha papkalarni aylantiradi va har bir papkada mavjud bo‘lgan .yaml fayllarini src/main/resources/static/swagger-apis/ ostiga nusxalaydi.
private List<File> createFilesFromExternalDir() throws IOException {
String externalDir = "../swagger-apis/";
String innerDir = "src/main/resources/static/swagger-apis/";
List<String> externalFilePaths = Files.list(Paths.get(externalDir))
.filter(path -> Files.isDirectory(path))
.map(path -> Files.list(path)
.filter(f -> f.toString().contains(".yaml"))
.findFirst().get())
.map(path -> path.getParent().getFileName() + "/" + path.getFileName())
.toList();
return externalFilePaths.stream()
.map(filePath -> {
File newFile = new File(innerDir + filePath);
Files.createDirectories(newFile.toPath().getParent());
Files.copy(
Paths.get(externalDir + filePath),
Paths.get(newFile.getPath()),
StandardCopyOption.REPLACE_EXISTING
);
return newFile;
})
.toList();
}
Statik resurslar maydoniga nusxalangan YAML /swagger-apis/api2/swagger.yaml kabi URL orqali kirish mumkin va Swagger UI ushbu URL ni o‘qib, API hujjatlarini aks ettiradi. Operatsion struktura sifatida o‘zgarishi holatida, hozirgi nisbiy yo‘lga joylashtirilgan tashqi spetsifikatsiya saqlash joyining yo‘lini sozlama sifatida ajratish kerak bo‘ladi.
Custom Annotation asosida kutubxona yo‘nalishi
PoC kengaytirish yo‘nalishi, ushbu loyihani umumiy kutubxona qilishga qaratilgan edi. Har bir ishlab chiquvchi jamoa o‘z loyihasiga ushbu kutubxonani bog'lash sifatida qo‘shadi va spetsifikatsiya qilmoqchi bo‘lgan APIga Custom Annotation ni qo‘shadi. Keyin loyiha tarqatilgandan so‘ng kutubxona ishlaydi va annotation qo‘shilgan APIlarni qidiradi.
Ushbu yondashuv mijozlar muhitining cheklovlarini aylanib o‘tgan holda ishlab chiquvchilarning foydalanish imkoniyatlarini oshirishga qaratilgan. Ishlab chiquvchilar murakkab Swagger sozlamalari bilan bevosita shug‘ullanishlari shart emas, faqat spetsifikatsiya qilinadigan APIga annotation qo‘shishlari kifoya. Kutubxona Controller yoki Handler ma'lumotlariga asoslanib requestBody va response VO ni tahlil qiladi va Swagger YAML yaratish uchun zarur bo‘lgan ma'lumotlarni to‘playdi.
-
API identifikatsiyasi: Custom Annotation qo‘shilgan API metodlarini qidiradi.
-
So‘rov tahlili: requestBody turi va maydon tuzilishini aylantiradi.
-
Javob tahlili: response VO turi va ichki maydon tuzilishini aylantiradi.
-
YAML yaratish: Swagger 2.0 formatiga muvofiq paths, parameters, definitions, responses ni tuzadi.
-
Serverga aks ettirish: Yaratilgan YAML faylini Swagger serveri o‘qiy oladigan joyda yaratadi yoki yuboradi.
Ushbu tuzilma yakunlanganda API spetsifikatsiyasini yangilash tarqatish jarayoniga tabiiy ravishda ulanishi mumkin. Loyiha tarqatilganda kutubxona annotation qo‘shilgan APIga asoslangan YAML yaratadi va markaziy Swagger server o‘zgargan YAML ni o‘qib, Swagger UI ga aks ettiradi.
YAML yaratish loyihasining roli
swagger-file-generator Java ob'ekt modeli yordamida Swagger YAML faylini yaratish mumkinligini tekshirish uchun tajriba loyihasidir. Hozirgi amalga oshirish Swagger hujjatining asosiy tuzilmalari VO klasslari sifatida ifodalanishi va har bir ob'ektning toString() metodida YAML qatorini yig‘ish usulida amalga oshiriladi.
Ushbu loyiha to‘liq kutubxona sifatida emas, balki annotation asosidagi spetsifikatsiya yaratish kutubxonasini yaratishdan oldin zarur bo‘lgan YAML yaratish lojiqasining imkoniyatlarini tekshirish shaklida bo‘ladi. requestBody va response VO ni aylantirgandan so‘ng natijalarni SwaggerDefinition, SwaggerProperty, SwaggerParameter kabi ob'ektlarga joylab, oxirgi Swagger YAML fayliga aylantirish mumkin.
SwaggerYamlContentFactory factory = SwaggerYamlContentFactory.builder()
.info(SwaggerInfo.builder()
.description("This is build test")
.version("1.0.0")
.title("TEST").build())
.host("localhost:8080")
.basePath("/execute")
.paths(Arrays.asList(
SwaggerPath.builder()
.url("/v1/tenants/KOREA/sample")
.httpMethod("post")
.tag("test")
.summary("For Sample Test")
.parameters(Arrays.asList(
SwaggerParameter.builder()
.name("SampleQdo")
.inType("body")
.required(true)
.type("object")
.description("sample qdo").build()))
.responses(Arrays.asList(
SwaggerResponse.builder()
.code("200")
.description("sample response").build()))
.build()))
.build();
String yamlFormat = factory.toString();
FileGenerator.writeObjectToFile(
yamlFormat,
FileGenerator.createInnerDirAndFile("test")
);
Ushbu test kodi Java ob'ektlarini yig'ib, factory.toString() orqali YAML satrini hosil qiladi va FileGenerator orqali swagger.yaml fayliga saqlanadi. Haqiqiy kutubxona bosqichida bu ob'ektni yaratish qismi refleksiya asosidagi analiz natijalari bilan almashtirilishi mumkin.
Swagger hujjat modeli usuli
SwaggerYamlContentFactory Swagger hujjatining umumiy qismini yig'ish rolini o'ynaydi. Ichida info, host, basePath, paths, commonParameters, commonDefinitions mavjud bo'lib, har bir maydonni tartib bilan satrga aylantiradi.
@Getter
@Builder
public class SwaggerYamlContentFactory {
private SwaggerInfo info;
private String host;
private String basePath;
private List<SwaggerPath> paths;
private List<SwaggerParameter> commonParameters;
private List<SwaggerDefinition> commonDefinitions;
@Override
public String toString() {
return getBasicFormat()
+ getPathsFormat()
+ getCommonParametersFormat()
+ getCommonDefinitionsFormat();
}
}
Ushbu model Swagger hujjatining tuzilishi bilan deyarli bir-biriga mos keladi. SwaggerPath API URL va HTTP usuli, parametr, javobni ifodalaydi, SwaggerDefinition esa so'rov yoki javob VO ning sxema ta'rifini ifodalaydi. SwaggerProperty VO ichidagi maydonni Swagger property ga aylantirish rolini o'ynaydi.
|
Sinf |
Swagger maydoni |
Asosiy rol |
|---|---|---|
|
SwaggerInfo |
info |
Hujjat ta'rifi, versiya, sarlavha ma'lumotlarini tashkil etadi. |
|
SwaggerPath |
paths |
API URL, HTTP usuli, parametr, javobni tashkil etadi. |
|
SwaggerParameter |
parameters |
header, query, body parametrlarini ifodalaydi. |
|
SwaggerDefinition |
ta'riflar |
request/response VO ning sxemasini ifodalaydi. |
|
SwaggerProperty |
xususiyatlar |
VO maydonlarining turi, misol, izohlarini ifodalaydi. |
|
SwaggerResponse |
javoblar |
javob kodi va sxema havolasini ifodalaydi. |
Ushbu model qilish kutubxona qilishda muhim asos bo'ladi. annotation qo'shilgan API ni topib, requestBody va response VO ni aylanib o'tgach, natijani yuqoridagi obyektlarga bog'lash mumkin. Keyin obyektni YAML ga seriyalash orqali Swagger UI o'qiy oladigan spetsifikatsiya faylini yaratish mumkin.
Umumiy harakat oqimi
Nihoyat yo'naltirilgan tuzilma har bir ishlab chiqish jamoasi loyihasi, umumiy Swagger yaratish kutubxonasi, markaziy Swagger serveri, Swagger UI ni bog'laydigan oqimdir. Ishlab chiqish jamoasi o'z loyihasiga kutubxonani qo'shib, annotation qo'shadi. Tarqatish vaqtida kutubxona API va VO ni tahlil qilib, YAML faylini yaratadi. Markaziy Swagger serveri yaratilgan YAML ni to'plab, UI ga aks ettiradi.
각 개발팀 프로젝트
custom annotation 적용
↓
공통 Swagger 생성 라이브러리
annotation 대상 API 분석
requestBody / response VO 순회
swagger.yaml 생성
↓
Swagger 서버
YAML 파일 수집 및 리소스 등록
↓
Swagger UI
전사 개발팀이 배포 API 명세 확인
Ushbu oqim xizmatlarga oid Swagger sozlamalarini minimallashtirgan holda, mijozlarimiz uchun kerakli Swagger UI asosida spetsifikatsiya ko'rish tajribasini taqdim etadi. Shuningdek, API spetsifikatsiyasini yaratish mas'uliyatini umumiy kutubxonaga to'plagani uchun ishlab chiqish jamoalari o'rtasidagi amalga oshirish farqini kamaytirishi mumkin.
Kutilayotgan ta'sir
Birinchi kutish ta'siri API spetsifikatsiyasi kirish imkoniyatining oshishidir. Barcha ishlab chiqish jamoalari markaziy Swagger UI ga kirib hozirgi tarqatilgan API spetsifikatsiyasini tekshirishlari mumkin. API ni ta'minlaydigan jamoa va foydalanadigan jamoa bir xil ekran asosida aloqada bo'lishlari mumkin, shuning uchun hamkorlik xarajatlari kamayadi.
Ikkinchi kutish ta'siri hujjatlarni yangilash yukini kamaytirishdir. Maxsus Annotatsiya asosida kutubxona yaratish tugallangandan so'ng, dasturchilar spetsifikatsiyaga mo'ljallangan API ga annotatsiya qo'shib YAML yaratish jarayonida ishtirok etishlari mumkin. Tarqatish paytida requestBody va response VO ga asoslanib spetsifikatsiya yaratiladi, shuning uchun qo'lda hujjat yozishdan ko'ra yo'qotish imkoniyatini kamaytiradi.
Uchinchi kutish ta'siri mavjud muhit cheklovlarini saqlab qolish bilan birgalikda Swagger olib kelish samarasini olish imkoniyatidir. Har bir xizmat Swagger kutubxonasini to'g'ridan-to'g'ri chuqur integratsiya qilishishi shart emas, markaziy Swagger serveri va umumiy kutubxona orqali Swagger UI asosida hujjatlashtirish tajribasini taqdim etish mumkin.
-
Barcha jamoalar uchun umumiy Swagger UI orqali API spetsifikatsiyalarini ko'rish joyini bitta joyga to'g'ri keltirish mumkin.
-
Ishlab chiquvchi jamoalar o'rtasidagi Swagger sozlamalari farqlarini kamaytirish va umumiy kutubxona asosida spetsifikatsiya yaratish usulini standartlashtirish mumkin.
-
Tarqatish jarayonini va spetsifikatsiya yaratish jarayonini bog'lab, eng so'nggi API standartlariga mos hujjatlashtirishni maqsad qilamiz.
PoCda aniqlangan cheklovlar
PoC bosqichining amalga oshirilishi imkoniyatlarni sinovdan o'tkazishga qaratilganligi sababli, operatsion qo'llash uchun takomillashtirish zarurliklari mavjud. Hozirgi swagger-demo tashqi YAML yo'lini nisbiy yo'l sifatida ishlatmoqda, bu esa bajarilish joyiga ta'sir ko'rsatadi. Operatsion muhitda bu yo'l parametrlar bilan ajratilishi va spetsifikatsiya fayl ombori aniq belgilanishi kerak.
Shuningdek, YAML yaratish loyihasi matn birikmasi usuli orqali Swagger hujjatlarini yaratadi. Ushbu usul tushunish uchun oson, ammo hujjat tuzilishi murakkablashganda, yo'qolish yoki joylashtirish xatosi yuzaga kelishi mumkin. Operatsiya darajasidagi kutubxonaga aylantirish uchun YAML seriyalash kutubxonasi yoki OpenAPI model ob'ektlaridan foydalanish usullarini ko'rib chiqish zarur bo'lishi mumkin.
Xulosa
Ushbu PoCning asosiy maqsadi mijozlar tashkilotining mavjud dasturchilik muhit cheklovlarini saqlab qolish bilan birga Swagger asosidagi API spetsifikatsiya taqdim etish usulini ta'tiqdan o'tkazishdir. Mijozlar Swagger orqali API spetsifikatsiyasini ko'rishni xohlashdi va dasturchi jamoasi qo'lda hujjat yozish va spetsifikatsiyani yangilash yukini kamaytirishga muhtoj edilar.
Buning uchun markaziy Swagger serverini tashkil etishdi va bir nechta Swagger YAML faylini Swagger UI dan tanlash va ko'rish imkoniyatini yaratish uchun ishlab chiqildi. Bundan tashqari, ushbu loyiha kutubxona sifatida yaratilib, har bir dasturchi jamoasi Foydalanish Annotatsiyasini qo'llasa, tarqatish paytida requestBody va response VO ni aylantirib, Swagger YAML ni yaratishni maqsad qildi.
Xulosa qilib aytganda, bu loyiha Swagger ni har bir xizmatga to'g'ridan-to'g'ri ulash usuli emas, balki umumiy kutubxona va markaziy Swagger serveri orqali API spetsifikatsiyalarini avtomatik yaratish va ulash usulini sinovdan o'tkazishdir. Mijozlar tashkilotining butun dasturchilik jamoasi bir xil Swagger UI da tarqatilgan API spetsifikatsiyasini ko'rish imkoniyatiga ega ekanligini anglatadi.
NZ