goswagger เบื้องต้น

pallat

Pallat Anchaleechamaikorn

Posted on February 8, 2024

goswagger เบื้องต้น

คนที่เขียน API ด้วย Go ถ้าอยากจะทำ swagger ให้คนเข้ามากดๆเล่นได้ มันมีวิธีทำหลายท่ามากๆ วันนี้จะมาแนะนำท่าของคนขี้เกียจเขียน annotation ซึ่งผมพยายามลองมาหลายท่า(ซึ่งอาจจะยังไม่หมด) แต่ก็เจอท่านี้ ซึ่งเข้าใจได้ไม่ยาก ใช้ง่ายโดยใช้

https://goswagger.io/

ก่อนอื่นก็ไปดูการติดตั้งในเพจเขาก่อน https://goswagger.io/install.html ซึ่งผมเลือกใช้วิธี Installing from source นะครับ

ถ้าเราอ่าน docs เข้าก็จะมี blog อ้างอิงที่ Generate swagger specification from Go source code

แต่เดี๋ยวผมจะเล่าให้อ่านกันในแบบของผมดูว่าจะเข้าใจไหมนะครับ

หลังจากติดตั้งตามคู่มือเรียบร้อย เราจะได้คำสั่ง swagger มาให้ใช้ โดยคำสั่งนี้มันจะสามารถ auto generate ไฟล์ swagger.yaml หรือ json ก็ได้จาก source code เพียงแต่ว่า เราอาจจะต้องไปเขียน aanotation (อีกแล้วเหรอ) แต่ว่าเขียนไม่เยอะเท่า swaggo

ก่อนอื่นให้เราไปสร้าง meta ของ docs(swagger) ไว้ที่ /docs/docs.go ก็คือไปสร้างไดเร็คทอรี่ชื่อ docs ไว้ที่ root ของ project แล้วสร้างไฟล์ docs.go ไว้ในนั้นนั่นเอง

ใน docs.go มีตัวอย่างให้แบบนี้ครับ

// Package classification MyApplication.
//
// Documentation of our MyApplication API.
//
//      Schemes: http
//      BasePath: /
//      Version: 1.0.0
//      Host: localhost:8080
//
//      Consumes:
//      - application/json
//
//      Produces:
//      - application/json
//
//      Security:
//      - key: []
//
//      SecurityDefinitions:
//      key:
//        type: apiKey
//        in: header
//        name: Authorization
//
// swagger:meta
package docs
Enter fullscreen mode Exit fullscreen mode

ตัวอย่างนี้ผมแก้ไขนิดหน่อยให้เหมาะกับที่ผมใช้ประจำ โดยเป็นการกำหนด basepath ให้เป็น localhost:8080 เพราะเวลาเรารันที่เครื่องเราจะได้ยิง API บนเครื่องเราได้เลย

ตรงส่วน security ปกติผมจะใช้ Authorization ใน header ก็เลยกำหนดลักษณะนี้ไว้ครับ

นี่เป็นส่วนของ meta ซึ่งจะเป็นเหมือนหัวเอกสารของเราว่ามันเป็น API ของอะไร(ในตัวอย่างคือชื่อ MyApplication)

จากนั้น เราจะไปเขียน route พร้อมกับ request/response กัน ซึ่งเราสามารถจะไปเขียนไว้ที่ไหนก็ได้ใน codebase ของเรา แล้วเดี๋ยวเราจะใช้คำสั่ง swagger ไป scan หามาให้เองครับ

ยกตัวอย่างเช่น ผมจะไปเขียน Handler ไว้ที่ ./app/user
ผมใช้วิธีไปสร้างไฟล์ docs.go ไว้ในนั้นอีกที เพื่อจะได้รู้ว่านี่คือส่วนของ docs โดยผมเขียนแบบนี้

package user

// swagger:route GET /users user getUserEndpointID
// responses:
//
//  200: userResponse
//  400: userBadRequestResponse
//  500: userErrorResponse

// swagger:response userResponse
type swaggerUserResponseWrapper struct {
    // in:body
    Body User
}

type User struct {
    Name string `json:"name"`
    Email string `json:"email"`
}

// swagger:response userBadRequestResponse
type swaggerUserBadRequestResponseWrapper struct {
    // in:body
    Body ErrorResponse
}

// swagger:response userErrorResponse
type swaggerUserErrorResponseWrapper struct {
    // in:body
    Body ErrorResponse
}

type ErrorResponse struct {
    Message string `json:"message"`
}
Enter fullscreen mode Exit fullscreen mode

อธิบายแบบนี้นะครับ

บรรทัด swagger:route syntax คือ

swagger:route [method] [path pattern] [?tag1 tag2 tag3] [operation id]

tag ก็คล้ายๆกับการจัดกลุ่ม โดยเราสามารถมีหลายๆ route ที่มี tag ชื่อเดียวกัน เราจะเห็นการจัดกลุ่มตาม tag ตอนที่เปิดหน้า swagger ขึ้นมา
operation id เป็น id ที่จะใช้ให้ input(parameter) refer ถึง จะได้รู้ว่าเป็น input ของ route ไหน

บรรทัด response: มันจะมีรายการของ response ว่า API ของเราจะมี response ได้กี่แบบ โดยจะกำหนดเป็น http status code จับคู่กับ response

บรรทัด swagger:response จะตามด้วยชื่อที่เราตั้ง โดยชื่อนี้จะถูกเอาไปจับคู่กับ status code ของ responses ด้านบน

บรรทัด //in:body เป็นการบอกว่า response ของเรานั้นเป็นแบบ Object โดยจะมี type User เป็นตัว represent ง่ายๆเลย เดี๋ยวมันจะสร้าง json ตาม struct ของ User ให้เอง

เอาแค่นี้ก่อน สมมุติว่า API ของเราเป็แบบ GET method แบบไม่ต้องส่งอะไรมาเลย แล้วจะได้ response ออกไปนะครับ หลังจากนี้เราจะไปใช้คำสั่ง swagger กัน

swagger generate spec -o ./docs/swagger.yaml --scan-models
Enter fullscreen mode Exit fullscreen mode

ผมใช้คำสั่งนี้เพื่อให้มัน scan หา annotation กับ model ต่างๆแล้วสร้างไฟล์ swagger.yaml ไปวางไว้ใน ./docs นะครับ

จากนั้นใช้คำสั่ง

swagger serve -F=swagger ./docs/swagger.yaml
Enter fullscreen mode Exit fullscreen mode

มันจะ render Swagger แล้วเปิด browser ให้เราเลย

ทีนี้ โดยปกติ API เราก็อาจจะมีแบบ get โดยส่ง path parameter เข้ามา เราก็จะทำแบบนี้ครับ

// swagger:route GET /users/{id} user getUserEndpointID

// swagger:parameters getUserEndpointID
type swaggerUserParamsWrapper struct {
    // Id of a User
    //
    // In: path
    ID string `json:"id"`
}
Enter fullscreen mode Exit fullscreen mode

แบบนี้ก็คือ เราจะรับค่า id เข้ามาเป็น path parameter

ต่อมา ถ้า request เข้ามาเป็น json ล่ะจะทำแบบไหน

// swagger:route POST /users user postUserEndpointID
// responses:
//
//  201:

// swagger:parameters postUserEndpointID
type swaggerAddUserParamsWrapper struct {
    // in:body
    Body User
}
Enter fullscreen mode Exit fullscreen mode

ที่บรรทัด // swagger:parameters postUserEndpointID เราจับคู่ postUserEndpointID กับ route ที่ ID เดียวกัน

นี่เป็นตัวอย่างเบื้องต้นนะครับ เมื่อเราได้ swagger.yaml มาแล้ว สำหรับคนที่ใช้ vscode ถ้ามี extension ก็จะสามารถ try ใน vscode ได้เลย ไม่ต้องให้ swagger serve ด้วย สะดวกสุดๆ

สำหรับรายละเอียดเพิ่มเติมต่างๆ อ่านใน document ของ goswagger ได้เลย ซึ่งก็มีไม่ครบ 🤣 ถ้าอยากได้อะไร google หาเพิ่มเองด้วยก็ดีครับ

หวังว่าจะเป็นประโยชน์นะครับ

💖 💪 🙅 🚩
pallat
Pallat Anchaleechamaikorn

Posted on February 8, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related