Astra can be temperamental when extracting documentation for external types, sometimes they will all be documented perfectly, some will be documented or none at all will be.
type TimeResponse struct {
NewTime time.Time json:"new_time"
}
func main() {
r := gin.Default()
r.GET("/addtime/:duration", func(c *gin.Context) {
// Get the duration parameter from the path
durationStr := c.Param("duration")
// Parse the duration string to time.Duration
duration, err := time.ParseDuration(durationStr)
if err != nil {
// Handle the error and return a JSON response
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("Invalid duration: %s", err.Error())})
return
}
// Add the duration to the current time
resultTime := time.Now().Add(duration)
// Return the result in the response
response := TimeResponse{
NewTime: resultTime,
}
c.JSON(http.StatusOK, response)
})
gen := astra.New(inputs.WithGinInput(r), outputs.WithOpenAPIOutput("openapi.generated.yaml"))
config := astra.Config{
Title: "Example API",
Version: "1.0.0",
Host: "localhost",
Port: 8080,
}
gen.SetConfig(&config)
err := gen.Parse()
if err != nil {
panic(err)
}
// Run the server on port 8080
r.Run(":8080")
}
2. Install dependencies: `go get .`
3. Run `main.go`: `go run main.go`
## Expected Behaviour
Bellow is the expected output in `openapi.generated.yaml` from running `main.go`.
```yaml
openapi: 3.0.0
info:
title: Example API
description: Generated by astra
contact: {}
license:
name: ""
version: 1.0.0
servers:
- url: http://localhost:8080
paths:
/addtime/{duration}:
get:
parameters:
- name: duration
in: path
required: true
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
$ref: '#/components/schemas/main.TimeResponse'
"400":
description: ""
content:
application/json:
schema:
$ref: '#/components/schemas/gin.H'
components:
schemas:
gin.H:
type: object
additionalProperties: {}
description: H is a shortcut for map[string]any
main.TimeResponse:
type: object
properties:
new_time:
$ref: '#/components/schemas/time.Time'
time.Time:
type: string
format: date-time
description: |-
A Time represents an instant in time with nanosecond precision.
Programs using times should typically store and pass them as values,
not pointers. That is, time variables and struct fields should be of
type time.Time, not *time.Time.
A Time value can be used by multiple goroutines simultaneously except
that the methods GobDecode, UnmarshalBinary, UnmarshalJSON and
UnmarshalText are not concurrency-safe.
Time instants can be compared using the Before, After, and Equal methods.
The Sub method subtracts two instants, producing a Duration.
The Add method adds a Time and a Duration, producing a Time.
The zero value of type Time is January 1, year 1, 00:00:00.000000000 UTC.
As this time is unlikely to come up in practice, the IsZero method gives
a simple way of detecting a time that has not been initialized explicitly.
Each Time has associated with it a Location, consulted when computing the
presentation form of the time, such as in the Format, Hour, and Year methods.
The methods Local, UTC, and In return a Time with a specific location.
Changing the location in this way changes only the presentation; it does not
change the instant in time being denoted and therefore does not affect the
computations described in earlier paragraphs.
Representations of a Time value saved by the GobEncode, MarshalBinary,
MarshalJSON, and MarshalText methods store the Time.Location's offset, but not
the location name. They therefore lose information about Daylight Saving Time.
In addition to the required “wall clock” reading, a Time may contain an optional
reading of the current process's monotonic clock, to provide additional precision
for comparison or subtraction.
See the “Monotonic Clocks” section in the package documentation for details.
Note that the Go == operator compares not just the time instant but also the
Location and the monotonic clock reading. Therefore, Time values should not
be used as map or database keys without first guaranteeing that the
identical Location has been set for all values, which can be achieved
through use of the UTC or Local method, and that the monotonic clock reading
has been stripped by setting t = t.Round(0). In general, prefer t.Equal(u)
to t == u, since t.Equal uses the most accurate comparison available and
correctly handles the case when only one of its arguments has a monotonic
clock reading.
Actual Behaviour
Bellow is the worst case output in openapi.generated.yaml from running main.go. It can have sometimes have both, either or none of gin.H and time.Time documented but it is very it and miss.
Issue Description
Astra can be temperamental when extracting documentation for external types, sometimes they will all be documented perfectly, some will be documented or none at all will be.
Steps to Reproduce
main.go
with this content:import ( "fmt" "net/http" "time"
)
type TimeResponse struct { NewTime time.Time
json:"new_time"
}func main() { r := gin.Default()
}
Actual Behaviour
Bellow is the worst case output in
openapi.generated.yaml
from runningmain.go
. It can have sometimes have both, either or none ofgin.H
andtime.Time
documented but it is very it and miss.Additional Information