swaggo / swag

Automatically generate RESTful API documentation with Swagger 2.0 for Go.
MIT License
10.79k stars 1.21k forks source link

[Q&A] How to give examples to objects in line #1896

Open xorima opened 1 month ago

xorima commented 1 month ago

Describe the bug In the documentation it says I can give detail to the generated examples in the below maner, but when I try this I get an error:

Readme example:

Model composition in response

// JSONResult's data field will be overridden by the specific type proto.Order
@success 200 {object} jsonresult.JSONResult{data=proto.Order} "desc"

type JSONResult struct {
    Code    int          json:"code" 
    Message string       json:"message"
    Data    interface{}  json:"data"
}

error got on my code : 2024/10/06 12:45:03 ParseComment error in file /Users/jfield/dev/xorima/github-bridge/internal/app/webhook.go :invalid type: Response{status=200,message=

To Reproduce Code: file: app/webhook.go

package app

import (
    "github.com/xorima/slogger"
    "log/slog"
    "net/http"
)

type WebhookHandler struct {
    log *slog.Logger
}

func NewWebhookHandler(log *slog.Logger) *WebhookHandler {
    return &WebhookHandler{
        log: log.With(slog.String("handler", "webhook")),
    }
}

// Post - Receives the GitHub webhooks
//
//  @Summary        This API is there to receive the GitHub events.
//  @Description    Once received, this will add them to the event stream for consumers.
//  @Tags           Webhooks
//  @Accept         json
//  @Produce        json
//  @Success        200 {object} Response{status=200,message="Success"} "Successful Response"
//  @Failure            401 {object} Response{status=401,message="Unauthorized"}    "Unauthorized"
//  @Failure          404   {object} Response{status=404,message="Not Found"}       "Failure Response"
//  @Router         /api/v1/webhook/github [post]
func (wh *WebhookHandler) Post(w http.ResponseWriter, r *http.Request) {
    wh.log.Info("got request")
    resp := NewResponse(http.StatusAccepted, "Accepted")
    w.WriteHeader(resp.Status)
    _, err := w.Write(resp.ToJson())
    if err != nil {
        wh.log.Error("failure in writing webhook response", slogger.ErrorAttr(err))
    }
}

func (wh *WebhookHandler) RegisterRoutes(r Router) {
    r.Post("/v1/webhook/github", wh.Post)
}

file: app/response.go

package app

import "encoding/json"

type Response struct {
    Status  int    `json:"status"`
    Message string `json:"message"`
}

func NewResponse(status int, message string) *Response {
    return &Response{Status: status, Message: message}
}

func (r *Response) ToJson() []byte {
    // the error here is impossible due to well known object.
    resp, _ := json.Marshal(r)
    return resp
}

Expected behavior swag init generates with appropriate examples

Screenshots

image

Your swag version 1.16.3

Your go version e.g. 1.12.0

Additional context I am doing this so I will not have to create multiple structs that are identical but have different examples, as that would add complexity which is not desired

martinyonatann commented 1 month ago

based on attachment readme. the code should be like this

type Response struct {
    Status int `json:"status"`
    Data   any `json:"data"`
}

type DTOs struct {
    A string `json:"a" example:"a"`
    B string `json:"b" example:"b"`
    C string `json:"b" example:"c"`
}
// Post - Receives the GitHub webhooks
//
//  @Summary        This API is there to receive the GitHub events.
//  @Description    Once received, this will add them to the event stream for consumers.
//  @Tags           Webhooks
//  @Accept         json
//  @Produce        json
//  @Success        200 {object} Response{data=DTOs}    "Successful Response"
//  @Router         /api/v1/webhook/github [post]
func (wh *WebhookHandler) Post(w http.ResponseWriter, r *http.Request) {
    wh.log.Info("got request")
    resp := NewResponse(http.StatusAccepted, "Accepted")
    w.WriteHeader(resp.Status)
    _, err := w.Write(resp.ToJson())
    if err != nil {
        wh.log.Error("failure in writing webhook response", slogger.ErrorAttr(err))
    }
}
xorima commented 1 month ago

Thanks @martinyonatann

using the example has gotten closer, but still not fully there

image

this is using this as the example:

type Response struct {
    Status  int    `json:"status"`
    Message string `json:"message"`
}

type Success struct {
    A int `json:"status" example:"200"`
}
//  @Success        202 {object} Response{status=Success}   "Successful Response"

It feels like I will have to make a custom response type for each, which while not end of the world it's not what I originally intended :)