Skip to content

Commit cc80a77

Browse files
author
Jamie Tanna
committed
q
Signed-off-by: Jamie Tanna <jamie.tanna@elastic.co>
1 parent 4495985 commit cc80a77

File tree

1 file changed

+193
-18
lines changed

1 file changed

+193
-18
lines changed

README.md

Lines changed: 193 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -505,42 +505,200 @@ authorization, etc. Note that middlewares are server-specific.
505505

506506
### Generating API clients
507507

508-
**??**
508+
As well as generating the server-side boilerplate, `oapi-codegen` can also generate API clients.
509509

510-
This produces code such as:
510+
For instance, given an `api.yaml`:
511511

512-
```go
513-
// TODO
512+
```yaml
513+
openapi: "3.0.0"
514+
info:
515+
version: 1.0.0
516+
title: Generate models
517+
paths:
518+
/client:
519+
get:
520+
operationId: getClient
521+
responses:
522+
200:
523+
content:
524+
application/json:
525+
schema:
526+
$ref: "#/components/schemas/ClientType"
527+
put:
528+
operationId: updateClient
529+
responses:
530+
400:
531+
content:
532+
application/json:
533+
schema:
534+
type: object
535+
properties:
536+
code:
537+
type: string
538+
required:
539+
- code
540+
components:
541+
schemas:
542+
ClientType:
543+
type: object
544+
required:
545+
- name
546+
properties:
547+
name:
548+
type: string
549+
# NOTE that this is not generated by default because it's not referenced. If you want it, you need to use the following YAML configuration:
550+
#
551+
# output-options:
552+
# skip-prune: true
553+
Unreferenced:
554+
type: object
555+
required:
556+
- id
557+
properties:
558+
id:
559+
type: int
560+
```
561+
562+
And a `cfg.yaml`:
563+
564+
```yaml
565+
package: client
566+
output: client.gen.go
567+
generate:
568+
models: true
569+
client: true
514570
```
515571

516-
You are then able to **??**.
572+
And a `generate.go`:
517573

518574
```go
575+
package client
519576
577+
//go:generate go run github.com/deepmap/oapi-codegen/v2/cmd/oapi-codegen -config cfg.yaml api.yaml
520578
```
521579

522-
### Generating API models
580+
This would then generate:
523581

524-
If you're looking to only generate the models for interacting with a remote service, for instance if you need to hand-roll the API client for whatever reason, you can do this as-is.
582+
```go
583+
package client
525584
526-
For instance, given a `generate.go`:
585+
// ...
527586
528-
```go
529-
package onlymodels
587+
// ClientType defines model for ClientType.
588+
type ClientType struct {
589+
Name string `json:"name"`
590+
}
530591

531-
//go:generate go run github.com/deepmap/oapi-codegen/v2/cmd/oapi-codegen -config cfg.yaml api.yaml
592+
// ...
593+
594+
// Client which conforms to the OpenAPI3 specification for this service.
595+
type Client struct {
596+
// The endpoint of the server conforming to this interface, with scheme,
597+
// https://api.deepmap.com for example. This can contain a path relative
598+
// to the server, such as https://api.deepmap.com/dev-test, and all the
599+
// paths in the swagger spec will be appended to the server.
600+
Server string
601+
602+
// Doer for performing requests, typically a *http.Client with any
603+
// customized settings, such as certificate chains.
604+
Client HttpRequestDoer
605+
606+
// A list of callbacks for modifying requests which are generated before sending over
607+
// the network.
608+
RequestEditors []RequestEditorFn
609+
}
610+
611+
// ...
612+
613+
// The interface specification for the client above.
614+
type ClientInterface interface {
615+
// GetClient request
616+
GetClient(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)
617+
618+
// UpdateClient request
619+
UpdateClient(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)
620+
}
621+
622+
// ...
623+
624+
// ClientWithResponsesInterface is the interface specification for the client with responses above.
625+
type ClientWithResponsesInterface interface {
626+
// GetClientWithResponse request
627+
GetClientWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetClientResponse, error)
628+
629+
// UpdateClientWithResponse request
630+
UpdateClientWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*UpdateClientResponse, error)
631+
}
632+
633+
type GetClientResponse struct {
634+
Body []byte
635+
HTTPResponse *http.Response
636+
JSON200 *ClientType
637+
}
638+
639+
// ...
532640
```
533641

534-
And a `cfg.yaml`:
642+
With this generated client, it is then possible to construct and utilise the client, for instance:
535643

536-
```yaml
537-
package: onlymodels
538-
output: only-models.gen.go
539-
generate:
540-
models: true
644+
```go
645+
package client_test
646+
647+
import (
648+
"context"
649+
"fmt"
650+
"log"
651+
"net/http"
652+
653+
"github.com/deepmap/oapi-codegen/v2/examples/client"
654+
)
655+
656+
func TestClient_canCall() {
657+
// custom HTTP client
658+
hc := http.Client{}
659+
660+
// with a raw http.Response
661+
{
662+
c, err := client.NewClient("http://localhost:1234", client.WithHTTPClient(&hc))
663+
if err != nil {
664+
log.Fatal(err)
665+
}
666+
667+
resp, err := c.GetClient(context.TODO())
668+
if err != nil {
669+
log.Fatal(err)
670+
}
671+
if resp.StatusCode != http.StatusOK {
672+
log.Fatalf("Expected HTTP 200 but received %d", resp.StatusCode)
673+
}
674+
}
675+
676+
// or to get a struct with the parsed response body
677+
{
678+
c, err := client.NewClientWithResponses("http://localhost:1234", client.WithHTTPClient(&hc))
679+
if err != nil {
680+
log.Fatal(err)
681+
}
682+
683+
resp, err := c.GetClientWithResponse(context.TODO())
684+
if err != nil {
685+
log.Fatal(err)
686+
}
687+
if resp.StatusCode() != http.StatusOK {
688+
log.Fatalf("Expected HTTP 200 but received %d", resp.StatusCode())
689+
}
690+
691+
fmt.Printf("resp.JSON200: %v\n", resp.JSON200)
692+
}
693+
694+
}
541695
```
542696

543-
And an `api.yaml`:
697+
### Generating API models
698+
699+
If you're looking to only generate the models for interacting with a remote service, for instance if you need to hand-roll the API client for whatever reason, you can do this as-is.
700+
701+
For instance, given an `api.yaml`:
544702

545703
```yaml
546704
openapi: "3.0.0"
@@ -595,6 +753,23 @@ components:
595753
type: int
596754
```
597755
756+
And a `cfg.yaml`:
757+
758+
```yaml
759+
package: onlymodels
760+
output: only-models.gen.go
761+
generate:
762+
models: true
763+
```
764+
765+
And a `generate.go`:
766+
767+
```go
768+
package onlymodels
769+
770+
//go:generate go run github.com/deepmap/oapi-codegen/v2/cmd/oapi-codegen -config cfg.yaml api.yaml
771+
```
772+
598773
This would then generate:
599774

600775
```go

0 commit comments

Comments
 (0)