Todo => task one
ต่อจากบทความก่อนหน้านี้ ที่ได้เกริ่นเอาไว้ว่าเราจะมาเพิ่ม Swagger เพื่อให้เราสามารถทดสอบ API ได้ง่ายขึ้นกันนะครับ โดยที่มีโจทย์ว่าตัว Swagger ที่เราจะทำการเพิ่มเข้ามา จะต้องรองรับการใช้งานกับ API หลาย Versions ..
หากจะถามว่าทำใม API เราต้องมีหลาย Versions ด้วยละ คำตอบคือ.. API ของเราไม่จำเป็นต้องทำขึ้นมาเพื่อให้ใช้งานได้เฉพาะ Front-End ตัวเดียว หรือในอนาคตโปรเจคเราเองอาจจะจำเป็นต้องทำ Mobile Application ขึ้นมา เราจะทำอย่างไร ยกตัวอย่างเช่น การโหลดข้อมูลทีละมากๆ ในหน้าแสดงรายการของ Task สำหรับ หน้า Front-End เราอาจจะใช้ library ที่ชื่อว่า datatables.js ในการแสดงข้อมูล ซึ่งเราอาจจะทำให้ API ดึงข้อมูลขึ้นมาทั้งหมดได้ในทีเดียว เพราะ datatables.js จะเป็นตัวจัดการการแสดงผลข้อมูลทั้งหมดเอง
แต่สำหรับ Mobile Application เองนั้นไม่สามารถทำแบบนั้นได้ เนื่องจากปัจจัยหลายๆ อย่างที่เป็นข้อจำกัด โดยเราอาจจะออกแบบ API ให้รองรับ Design ของ Mobile แบบ scroll down แล้วค่อยดึงข้อมูลมาแสดง ซึ่งในส่วนนี้เราจะทำเป็นอีก API อีก Version เพื่อไม่ให้กระทบกับ API ที่มีการใช้งานอยู่ก่อนแล้วครับ
เริ่มต้นเราจะสร้างโปรเจคใหม่ขึ้นมาโดยให้เลือกเป็นประเภท Class Library (.NET Core) และให้ตั้งชื่อว่า Todo.Extensions และให้เก็บโค๊ดเอาไว้ในโฟลเดอร์ src
จากนั้นเราก็จะทำการติดตั้ง Package จาก NuGet โดยจะมีรายชื่อ ดังนี้
Microsoft.AspNetCore.Mvc.Versioning
Swashbuckle.AspNetCore
Swashbuckle.AspNetCore.Filters
Swashbuckle.AspNetCore.ReDoc
Swashbuckle.AspNetCore.Swagger
Swashbuckle.AspNetCore.SwaggerGen
Swashbuckle.AspNetCore.SwaggerUI
Swashbuckle.AspNetCore.Annotations
Microsoft.Extensions.Configuration
Microsoft.Extensions.Configuration.Binder
Microsoft.Extensions.Configuration.EnvironmentVariables
Microsoft.Extensions.Configuration.CommandLine
Microsoft.Extensions.Configuration.FileExtensions
Microsoft.Extensions.Configuration.Json
Microsoft.Extensions.Options
Microsoft.Extensions.Options.ConfigurationExtensions
อาจจะเยอะไปหน่อย แต่เอาไว้เดี๋ยวค่อยมาทำอย่างอื่นต่อทีหลังครับ จากนั้นให้สร้างโฟลเดอร์ Swaggers และลบไฟล์ Class1.cs ทิ้ง หรือจะย้ายไฟล์นี้เข้าไปไว้ในโฟลเดอร์ฺก็ได้ครับ
จากนั้นสร้างไฟล์ชื่อ ApiVersionExtension.cs เพื่อใช้สำหรับเป็นตัวช่วยในการดึงเอา API Version มาใช้งานครับ
จากนั้นเราก็จะมาสร้างไฟล์ DocInclusionPredicateExtension.cs เพื่อใช้สำหรับเป็นตัวช่วยในการดึง Method Summary ของ API/Class ขึ้นมาแสดงบน Swagger
ปกติถ้าเราเรียกใช้ API บน Swagger ตัว Swagger จะบังคับให้เราระบุ Version ของ API ที่จะเรียกใช้งาน ดังนั้นเราเองเป็นคนขี้เกียจ เราก็จะมาเขียนคลาส RemoveVersionFromParameter.cs เพื่อที่จะไม่ต้องระบุ version กันครับ
และคลาส ReplaceVersionWithExactValueInPath เพื่อใช้สำหรับ Replace เลขของ version บน Url ของ API
จากนั้นเราก็จะมาทำ JsonIgnore สำหรับ Swagger สำหรับการ Filter route parameter เพิ่มกันครับ โดยผมจะสร้างไฟล์ชื่อ SwaggerJsonIgnore.cs และคำสั่งต่างๆ มีดังนี้
ต่อไปเราก็จะมาสร้าง Extension สำหรับ binding ข้อมูล Configuration เพื่อให้เรียกใช้งานง่ายๆ กันก่อนนะครับ โดยจะตั้งชื่อไฟล์ ConfigurationExtension.cs แต่เนื่องจากคลาสนี้ไม่ได้เป็นคลาสที่เกี่ยวข้องกับ Swagger โดยตรง ดังนั้นจะสร้างเอาไว้ข้างนอกโฟลเดอร์ Swaggers นะครับ ส่วนชุดคำสั่งมี ดังนี้
และขั้นตอนต่อไปเราจะสร้าง Class สำหรับเอา Config ต่างๆ ของ Swagger ที่เราสามารถกำหนดเอาไว้ใน Setting มา binding เป็น Object เพื่อให้เอามาใช้งานกับ Swagger สำหรับไฟล์นี้จะมีคำสั่ง ดังนี้
หลังจากที่เราทำการเตรียมคลาสต่างๆ ที่ต้องใช้เสร็จแล้ว ขั้นตอนต่อไปก็จะเป็นการสร้างคลาส SwaggerExtension ที่เป็นตัวหลักสำหรับการเรียกใช้งานกันแล้วครับ สำหรับไฟล์นี้จะสร้างเอาไว้ในโฟลเดอร์ Swaggers ครับ
สำหรับขั้นตอนในการสร้าง Swagger Extension ก็เสร็จแล้วครับ ขั้นต่อต่อไปเราก็จะมาเรียกใช้งาน Extension ที่เราสร้างกันครับ อย่าลืมทดลอง Build Project กันด้วยนะครับ
เริ่มแรกอย่าลืม Include Extension project ที่เราสร้างขึ้นมาก่อนนะครับ หลังจากนั้นให้เปิดไฟล์ Startup.cs ขึ้นมาก่อน และเราจะทำการเรียกใช้งาน Swagger กัน ดังนี้
และเปิดใช้งาน Swagger ในส่วนของ Config ดังนี้
ต่อไปเราก็จะต้องกลับไปทำ API Summary กัน โดยให้ดับเบิ้ลคลิกที่ไฟล์โปรเจคของเรา(Todo.API) และเพิ่มคำสั่งนี้เอาไว้ในส่วนเดียวกับ TargetFramework
<GenerateDocumentationFile>true</GenerateDocumentationFile>
และเพิ่มคำสั่งนี้ เพื่อระบุตำแหน่งสำหรับการเก็บไฟล์ Summary ของเราเอาไว้ในโฟลเดอร์ APP_DATA
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>APP_DATA\Todo.API.xml</DocumentationFile>
</PropertyGroup>
และเราจะย้าย Controller ไปไว้ในโฟลเดอร์ V1_0 ตามภาพ และอย่าลืมแก้ NameSpace ของ Controller ให้ตรงกับ Path ที่อยู่ด้วย
จากนั้นให้เปิดไฟล์ TodoController.cs ขึ้นมาเพื่อทำ Controller Summary กัน สำหรับวิธีสร้างจะใช้ syntax แบบนี้ครับ
/// <summary>
///
/// </summary>
โดยเราจะต้องเพิ่มให้ทั้ง Controller และ Method ทั้งหมด ดังนี้
** อย่าลืมแก้ไขในส่วนของ Route URL ใน Controller เราด้วยนะครับ
ขั้นตอนสุดท้ายก็จะเป็นการ Config ค่าต่างๆ ให้กับ API ของเรา เช่น API ของเราชื่ออะไร มี Version อะไรบ้าง ประมาณนี้ครับ ให้เราเปิดไฟล์ appsettings.json ขึ้นมา และเพิ่ม Config เข้าไปต่อท้าย Database Connection String ตามนี้ครับ
ให้เปิดไฟล์ launchSettings.json ขึ้นมา เพื่อแก้ไข path ที่ต้องการเรียกใช้งานตอนที่เราสั่ง run project ซึ่งของเดิมโปรเจคเราจะเริ่มโดยใช้ path ของ weatherforecast ให้เราแก้ไข path ให้ตรงกับ routePrefix ใน appsettings.json ที่เราพึ่งกำหนดไป
"launchUrl": "weatherforecast", ===> "launchUrl":"swagger",
จากนั้นให้ทดลองรันโปรเจคขึ้นมา เราก็จะได้หน้าจอของ Swagger เพื่อใช้ทดสอบ API ของเราแล้วครับ
จากนั้นทดลองสร้าง Controller ขึ้นมาอีกตัว แต่เราจะสร้างเป็น V2_0 กัน
และสำหรับโค๊ดภายในก็จะมีประมาณนี้
จากนั้นก็ไปเพิ่ม Config ให้กับ API ของเรากัน
เมื่อเสร็จแล้วก็ให้ลองรันโปรเจคขึ้นมา ก็จะพบว่า Swagger เองรองรับการใช้งาน API Versioning แล้ว
สำหรับบทความนี้ก็จบลงไปแล้ว หากมีข้อผิดพลาดประการใด ก็ขออภัยมา ณ ที่นี้ด้วยครับ
Source Code (todo-task-one-swagger) :
https://github.com/VatthanachaiW/todo-project.git