apigen
generates API client via execution environment such as curl
.
$ go get github.com/ktr0731/apigen
This example is located under here
apigen
requires *Definition
which describes methods the service has.
Following definition defines CreatePost
, ListPosts
, GetPost
, UpdatePost
and DeletePost
which belong to Dummy
service.
Request
specify execution environment, apigen
generates the API client and request/response types based on the execution result.
ParamHint
is only required when its method uses path parameters such as "/post/{postID}"
. apigen
generates the request type by using it.
The artifact will be written to client_gen.go
which is specified by apigen.WithWriter
. Default output is stdout.
package main
import (
"context"
"log"
"os"
"github.com/ktr0731/apigen"
"github.com/ktr0731/apigen/curl"
)
func main() {
def := &apigen.Definition{
Services: map[string][]*apigen.Method{
"Dummy": {
{
Name: "CreatePost",
Request: curl.ParseCommand(`curl 'https://jsonplaceholder.typicode.com/posts' --data-binary '{"title":"foo","body":"bar","userId":1}'`),
},
{
Name: "ListPosts",
Request: curl.ParseCommand(`curl https://jsonplaceholder.typicode.com/posts`),
},
{
Name: "GetPost",
Request: curl.ParseCommand(`curl https://jsonplaceholder.typicode.com/posts?id=1`),
},
{
Name: "UpdatePost",
Request: curl.ParseCommand(`curl 'https://jsonplaceholder.typicode.com/posts/1' -X 'PUT' --data-binary '{"title":"foo","body":"bar","userId":1}'`),
ParamHint: "/posts/{postID}",
},
{
Name: "DeletePost",
Request: curl.ParseCommand(`curl 'https://jsonplaceholder.typicode.com/posts/1' -X 'DELETE'`),
ParamHint: "/posts/{postID}",
},
},
},
}
f, err := os.Create("client_gen.go")
if err != nil {
log.Fatal(err)
}
defer f.Close()
if err := apigen.Generate(context.Background(), def, apigen.WithWriter(f)); err != nil {
log.Fatal(err)
}
}
The artifact is here.
We can invoke the API server using the generated API client.
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"github.com/ktr0731/apigen/client"
)
func main() {
client := NewDummyClient(client.WithInterceptors(client.ConvertStatusCodeToErrorInterceptor()))
res, err := client.GetPost(context.Background(), &GetPostRequest{ID: "10"})
if err != nil {
log.Fatal(err)
}
b, err := json.MarshalIndent(&res, "", " ")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b))
}
The output is:
[
{
"body": "quo et expedita modi cum officia vel magni\ndoloribus qui repudiandae\nvero nisi sit\nquos veniam quod sed accusamus veritatis error",
"id": 10,
"title": "optio molestias id quia eum",
"userId": 1
}
]