Saltar al contenido principal

Documenting Request Bodies (v2)

This guide shows how to document request bodies with Go-Swagger-Generator v2 for OpenAPI 3.0. Request bodies are typically used with POST, PUT, and PATCH operations to send data to the server.

Basic JSON Request Body​

Here's an example of documenting an endpoint (e.g., POST for creating a resource) that accepts a JSON request body.

package main

import (
"github.com/gin-gonic/gin"
"github.com/ruiborda/go-swagger-generator/v2/src/openapi"
"github.com/ruiborda/go-swagger-generator/v2/src/openapi_spec/mime"
"github.com/ruiborda/go-swagger-generator/v2/src/swagger"
"net/http"
)

// Pet DTO
type Pet struct {
ID int64 `json:"id,omitempty" yaml:"id,omitempty"`
Name string `json:"name" yaml:"name"`
PhotoUrls []string `json:"photoUrls" yaml:"photoUrls"`
Status string `json:"status,omitempty" yaml:"status,omitempty"` // e.g., available, pending, sold
}
// _, _ = swagger.Swagger().ComponentSchemaFromDTO(&Pet{})

// Swagger documentation for POST /pets
var _ = swagger.Swagger().Path("/pets"). // Path relative to server URL
Post(func(op openapi.Operation) {
op.Summary("Add a new pet to the store").
OperationID("addPetV2").
Tag("Pet Operations").
RequestBody(func(rb openapi.RequestBody) { // Define the request body
rb.Description("Pet object that needs to be added to the store").
Required(true).
Content(mime.ApplicationJSON, func(mt openapi.MediaType) { // Specify content type
mt.SchemaFromDTO(&Pet{}) // Generate schema from Pet DTO
})
// Optionally, support other content types like XML:
// rb.Content(mime.ApplicationXML, func(mt openapi.MediaType) {
// mt.SchemaFromDTO(&Pet{})
// })
}).
Response(http.StatusCreated, func(r openapi.Response) {
r.Description("Pet created successfully").
Content(mime.ApplicationJSON, func(mt openapi.MediaType) {
mt.SchemaFromDTO(&Pet{}) // Return the created pet
})
}).
Response(http.StatusBadRequest, func(r openapi.Response) {
r.Description("Invalid input provided")
})
}).
Doc()

// Handler function (example)
func AddPet(c *gin.Context) {
var pet Pet
if err := c.ShouldBindJSON(&pet); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"})
return
}
pet.ID = 123 // Simulate ID generation
// Save pet to database...
c.JSON(http.StatusCreated, pet)
}

Request Body with Custom Inline Schema​

If you don't have a DTO or need a very specific structure for a single request, you can define the schema inline.

package main

import (
"github.com/gin-gonic/gin"
"github.com/ruiborda/go-swagger-generator/v2/src/openapi"
"github.com/ruiborda/go-swagger-generator/v2/src/openapi_spec/mime"
"github.com/ruiborda/go-swagger-generator/v2/src/swagger"
"net/http"
)

// EventData structure for the example (could also be a DTO)
type EventData struct {
EventName string `json:"eventName"`
Timestamp string `json:"timestamp"`
Properties map[string]interface{} `json:"properties,omitempty"`
}

// Swagger documentation for POST /analytics/events
var _ = swagger.Swagger().Path("/analytics/events").
Post(func(op openapi.Operation) {
op.Summary("Track analytics events").
Description("Send one or more analytics events in a single request.").
OperationID("trackEventsV2").
Tag("Analytics Operations").
RequestBody(func(rb openapi.RequestBody) {
rb.Description("Analytics events payload").
Required(true).
Content(mime.ApplicationJSON, func(mt openapi.MediaType) {
mt.Schema(func(s openapi.Schema) { // Define schema inline
s.Type("object").
Required("userId", "events").
Property("userId", func(ps openapi.Schema) {
ps.Type("string").Description("Unique identifier for the user")
}).
Property("sessionId", func(ps openapi.Schema) {
ps.Type("string").Description("Current session identifier (optional)")
}).
Property("events", func(ps openapi.Schema) {
ps.Type("array").Description("List of events to track").MinItems(1).
Items(func(itemSchema openapi.Schema) { // Schema for each event in the array
itemSchema.Type("object").Required("eventName", "timestamp").
Property("eventName", func(prop openapi.Schema){ prop.Type("string") }).
Property("timestamp", func(prop openapi.Schema){ prop.Type("string").Format("date-time") }).
Property("properties", func(prop openapi.Schema){
prop.Type("object").Description("Additional key-value pairs for the event").
AdditionalProperties(true, openapi.S().Type("string")) // Example: all additional props are strings
})
})
})
})
})
}).
Response(http.StatusOK, func(r openapi.Response) {
r.Description("Events tracked successfully").
Content(mime.ApplicationJSON, func(mt openapi.MediaType) {
mt.Schema(func(s openapi.Schema) { // Response schema
s.Type("object").
Property("trackedCount", func(ps openapi.Schema){ ps.Type("integer") }).
Property("failedCount", func(ps openapi.Schema){ ps.Type("integer") })
})
})
}).
Response(http.StatusBadRequest, func(r openapi.Response) {
r.Description("Invalid event data provided")
})
}).
Doc()

// Handler function (example)
func TrackEvents(c *gin.Context) {
// var requestPayload struct { ... } // Define a struct to bind JSON
// if err := c.ShouldBindJSON(&requestPayload); ...
c.JSON(http.StatusOK, gin.H{"trackedCount": 1, "failedCount": 0})
}

Array as Request Body​

If the entire request body is an array of objects (e.g., bulk creation).

package main

import (
"github.com/gin-gonic/gin"
"github.com/ruiborda/go-swagger-generator/v2/src/openapi"
"github.com/ruiborda/go-swagger-generator/v2/src/openapi_spec/mime"
"github.com/ruiborda/go-swagger-generator/v2/src/swagger"
"net/http"
)

// User DTO (defined in earlier examples)
// type User struct { ... }
// _, _ = swagger.Swagger().ComponentSchemaFromDTO(&User{})

// Swagger documentation for POST /users/bulkCreate
var _ = swagger.Swagger().Path("/users/bulkCreate").
Post(func(op openapi.Operation) {
op.Summary("Creates multiple users from a list").
OperationID("createUsersWithListV2").
Tag("User Operations").
RequestBody(func(rb openapi.RequestBody) {
rb.Description("List of user objects to create").Required(true).
Content(mime.ApplicationJSON, func(mt openapi.MediaType) {
// For an array request body, use SchemaFromDTO with a pointer to a slice of DTO pointers
mt.SchemaFromDTO(&[]*User{})
})
}).
Response(http.StatusCreated, func(r openapi.Response) {
r.Description("Users created successfully (or report on status)")
// Response could be a summary, e.g., number created/failed
}).
Response(http.StatusBadRequest, func(r openapi.Response) {
r.Description("Invalid user data in the list")
})
}).
Doc()

// Handler function (example)
func CreateUsersWithList(c *gin.Context) {
var users []*User
if err := c.ShouldBindJSON(&users); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user data"})
return
}
// Implementation to create multiple users...
c.JSON(http.StatusCreated, gin.H{"message": "Users processed", "count": len(users)})
}

Form Data Request Body (application/x-www-form-urlencoded or multipart/form-data)​

For form data, the Content type is typically application/x-www-form-urlencoded or multipart/form-data. The schema describes the form fields.

application/x-www-form-urlencoded Example:

package main

import (
"github.com/gin-gonic/gin"
"github.com/ruiborda/go-swagger-generator/v2/src/openapi"
"github.com/ruiborda/go-swagger-generator/v2/src/openapi_spec/mime"
"github.com/ruiborda/go-swagger-generator/v2/src/swagger"
"net/http"
)

// Swagger documentation for POST /submit-feedback
var _ = swagger.Swagger().Path("/submit-feedback").
Post(func(op openapi.Operation) {
op.Summary("Submit user feedback via form").
OperationID("submitFeedbackV2").
Tag("Feedback Operations").
RequestBody(func(rb openapi.RequestBody) {
rb.Description("Feedback form data").Required(true).
Content(mime.ApplicationFormUrlEncoded, func(mt openapi.MediaType) {
mt.Schema(func(s openapi.Schema) {
s.Type("object").
Required("email", "message"). // Specify required form fields
Property("name", func(ps openapi.Schema){ ps.Type("string").Description("Your name (optional)") }).
Property("email", func(ps openapi.Schema){ ps.Type("string").Format("email").Description("Your email address") }).
Property("subject", func(ps openapi.Schema){ ps.Type("string").Description("Subject of feedback").Default("General Feedback") }).
Property("message", func(ps openapi.Schema){ ps.Type("string").Description("Your feedback message").MinLength(10) })
})
})
}).
Response(http.StatusOK, func(r openapi.Response) {
r.Description("Feedback submitted successfully")
}).
Response(http.StatusBadRequest, func(r openapi.Response) {
r.Description("Invalid form data provided")
})
}).
Doc()

// Handler function (example)
func SubmitFeedback(c *gin.Context) {
// name := c.PostForm("name")
// email := c.PostForm("email")
// ... process form data ...
c.JSON(http.StatusOK, gin.H{"message": "Feedback received!"})
}

For multipart/form-data (e.g., including file uploads), see the POST Endpoints (v2) guide.

Key elements for RequestBody:

  • Description(string): A description of the request body.
  • Required(bool): Whether the request body is mandatory.
  • Content(mimeType string, func(mt openapi.MediaType)): Defines one or more media types the endpoint consumes.
    • Inside Content, mt.SchemaFromDTO(&YourType{}) or mt.Schema(func(s openapi.Schema){...}) defines the structure of the data for that media type.