-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
146 lines (126 loc) · 3.78 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package main
import (
"context"
"fmt"
"log"
"net/http"
"github.com/danielgtaylor/huma/v2"
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi/v5"
)
// Options for the CLI.
type Options struct {
Port int `help:"Port to listen on" short:"p" default:"8888"`
}
// GreetingInput represents the greeting operation request.
type GreetingInput struct {
Name string `path:"name" maxLength:"30" example:"world" doc:"Name to greet"`
}
// GreetingOutput represents the greeting operation response.
type GreetingOutput struct {
Body struct {
Message string `json:"message" example:"Hello, world!" doc:"Greeting message"`
}
}
// ReviewInput represents the review operation request.
type ReviewInput struct {
Body struct {
Author string `json:"author" maxLength:"10" doc:"Author of the review"`
Rating int `json:"rating" minimum:"1" maximum:"5" doc:"Rating from 1 to 5"`
Message string `json:"message,omitempty" maxLength:"100" doc:"Review message"`
}
}
// Review represents a review.
type Review struct {
Author string `json:"author"`
Rating int `json:"rating"`
Message string `json:"message,omitempty"`
}
// Reviews represents the response of the "get all reviews" operation.
type ReviewsOutput struct {
Body struct {
Reviews []Review `json:"reviews"`
}
}
// Health represents the response of the "get health" operation.
type HealthOutput struct {
Body struct {
Status string `json:"status"`
}
}
func addRoutes(api huma.API) {
// Add GET / for health checks
huma.Register(api, huma.Operation{
OperationID: "get-health",
Summary: "Get health",
Method: http.MethodGet,
Path: "/",
DefaultStatus: http.StatusOK,
}, func(ctx context.Context, i *struct{}) (*HealthOutput, error) {
resp := &HealthOutput{}
resp.Body.Status = "ok"
return resp, nil
})
// Register GET /greeting/{name}
huma.Register(api, huma.Operation{
OperationID: "get-greeting",
Summary: "Get a greeting",
Method: http.MethodGet,
Path: "/greeting/{name}",
}, func(ctx context.Context, input *GreetingInput) (*GreetingOutput, error) {
resp := &GreetingOutput{}
resp.Body.Message = fmt.Sprintf("Hello, %s!", input.Name)
return resp, nil
})
reviews := make([]Review, 0)
// Add a POST /reviews
huma.Register(api, huma.Operation{
OperationID: "post-review",
Summary: "Post a review",
Method: http.MethodPost,
Path: "/reviews",
DefaultStatus: http.StatusCreated,
}, func(ctx context.Context, i *ReviewInput) (*struct{}, error) {
review := Review{
Author: i.Body.Author,
Rating: i.Body.Rating,
Message: i.Body.Message,
}
reviews = append(reviews, review)
return nil, nil
})
// Add a GET /reviews
huma.Register(api, huma.Operation{
OperationID: "get-all-reviews",
Summary: "Get all reviews",
Method: http.MethodGet,
Path: "/reviews",
}, func(ctx context.Context, i *struct{}) (*ReviewsOutput, error) {
resp := &ReviewsOutput{}
resp.Body.Reviews = reviews
return resp, nil
})
}
func main() {
// Create a CLI app which takes a port option.
cli := humacli.New(func(hooks humacli.Hooks, options *Options) {
// Create a new router & API
router := chi.NewMux()
api := humachi.New(router, huma.DefaultConfig("My Simple API", "1.0.0"))
addRoutes(api)
// Start the server!
addr := "http://127.0.0.1:" + fmt.Sprintf("%d", options.Port)
// Tell the CLI how to start your server.
hooks.OnStart(func() {
fmt.Printf("Starting server on port %d...\n", options.Port)
log.Printf("Go to %s/docs for documentation", addr)
err := http.ListenAndServe(fmt.Sprintf(":%d", options.Port), router)
if err != nil {
log.Fatal(err)
}
})
})
// Run the CLI. When passed no commands, it starts the server.
cli.Run()
}