-
-
Notifications
You must be signed in to change notification settings - Fork 150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Any way to create a CLI out of the web server? #585
Comments
@ashishb thanks! I'm glad you like it 😄 What are you hoping to do with your CLI? If you use the
If you are looking to have a CLI that calls into a running web server, take a look at Restish |
@danielgtaylor I have a set of API calls generated via huma and I want to automatically convert it into CLI |
@ashishb did you read the linked docs? I think they will show you how to do what you want. Let me know if you have specific questions! |
@danielgtaylor I did look at https://huma.rocks/tutorial/cli-client/ |
@ashishb you can use the custom commands docs I linked to if you want CLI commands for the server itself. Here's a modified hello world example: package main
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"github.com/danielgtaylor/huma/v2"
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/danielgtaylor/huma/v2/humatest"
"github.com/go-chi/chi/v5"
"github.com/spf13/cobra"
_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)
// 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"`
}
}
func main() {
var router *chi.Mux
// 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 API", "1.0.0"))
// 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
})
// Tell the CLI how to start your router.
hooks.OnStart(func() {
http.ListenAndServe(fmt.Sprintf(":%d", options.Port), router)
})
})
cli.Root().AddCommand(&cobra.Command{
Use: "get-greeting",
Short: "Greet someone",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
req := httptest.NewRequest(http.MethodGet, "/greeting/"+args[0], nil)
resp := httptest.NewRecorder()
router.ServeHTTP(resp, req)
humatest.PrintResponse(resp.Result())
},
})
// Run the CLI. When passed no commands, it starts the server.
cli.Run()
} You can run it like: $ go run . get-greeting bob
HTTP/1.1 200 OK
Connection: close
Content-Type: application/json
Link: </schemas/GreetingOutputBody.json>; rel="describedBy"
{
"$schema": "https://example.com/schemas/GreetingOutputBody.json",
"message": "Hello, bob!"
} You can write whatever commands you want this way and simulate a request to the server. If you don't want the overhead of HTTP request/response stuff, you can instantiate your handler's request struct manually and call it directly, then handle the response struct however you want, or factor out common code that both the CLI operation and handler can call. Hopefully this helps! |
Thanks for this awesome package.
Is there a way to convert my webserver into an offline CLI as well using
huma
?The text was updated successfully, but these errors were encountered: