Idiomatic Go client package generation from OpenAPI documents
Introduction | Examples | Usage | Configuration | Contributing | License
🚧 Disclaimer: oag
is alpha quality software. The API of generated code
and configuration file format may change without warning between revisions.
Please check your generated code before use! 🚧
oag
generates idiomatic Go client packages from OpenAPI documents.
OpenAPI 2.0 (née Swagger 2.0) is supported, with support for
OpenAPI 3.0.0 coming soon.
- Idiomatic Concise Code:
oag
generates code modeled after some of Go's best REST API clients, like GitHub and Stripe. - Extensible: Generated code is written to a single file. You are free to add your own files to the package, adding behaviour to the generated types.
- Fast: Code is generated in milliseconds.
- Commit Friendly: Generated code is deterministic and stable. Multiple runs produce the same output. Document additions and removals create clean diffs.
- Build Tool Friendly: If the generated code has not changed, nothing is
written, and timestamps stay the same. A run of
oag
won't needlessly trigger other targets inmake
. - Single File Output: All generated code is written to a single file. Removals from an OpenAPI document won't result in orphaned generated files.
Introduction | Examples | Usage | Configuration | Contributing | License
The minimal petstore OpenAPI 2.0 example (edited for brevity):
// Client is an API client for all endpoints.
type Client struct {
Pets *PetsClient
// contains filtered or unexported fields
}
// New returns a new Client with the default configuration.
func New() *Client {}
// Pet is a data type for API communication.
type Pet struct {
ID int `json:"id"`
Name string `json:"name"`
Tag *string `json:"tag"` // Optional
}
// PetIter Iterates over a result set of Pets.
type PetIter struct {
// contains filtered or unexported fields
}
// Close closes the PetIter and releases any associated resources. After
// Close, any calls to Current will return an error.
func (i *PetIter) Close() {}
// Current returns the current Pet, and an optional error. Once an error
// has been returned, the PetIter is closed, or the end of iteration is
// reached, subsequent calls to Current will return an error.
func (i *PetIter) Current() (*Pet, error) {}
// Next advances the PetIter and returns a boolean indicating if the end
// has been reached. Next must be called before the first call to Current.
// Calls to Current after Next returns false will return an error.
func (i *PetIter) Next() bool {}
// PetsClient provides access to the /pets APIs
type PetsClient endpoint
// List corresponds to the GET /pets endpoint. Returns all pets from the
// system that the user has access to
func (c *PetsClient) List(ctx context.Context) *PetIter {}
View the complete generated client code
Introduction | Examples | Usage | Configuration | Contributing | License
go get -u github.com/jbowes/oag
# In the directory under your $GOPATH where your package will live
oag init
# Edit the created .oag.yaml file, following the comments
oag
git add zz_oag_generated.go
git commit -m "Add autogenerated API client"
Implement the error interface for your error types
oag
can determine which types are used as errors, but it does not know how you
wish to present them.
Create a new file in the same package that implements error for your type. For
example, if zz_oag_generated.go
contained:
type APIError struct {
ID string `json:"id"`
Message string `json:"message"`
Class string `json:"class"`
}
Where ID
is some unique value generated per error, and Class
is a group of
error types, you could put the following in an error.go
file:
// Error returns a string representation of this error
func (a *APIError) Error() string {
return fmt.Sprintf("%s: %s (%s)", a.ID, a.Message, a.Class)
}
Introduction | Examples | Usage | Configuration | Contributing | License
oag
keeps its configuration in a separate file rather than relying on OpenAPI
vendor extensions. If you are not the original author of the OpenAPI document,
you don't need to carry patches to it to use oag
.
By default, the file .oag.yaml
is used for configuration. You may override
this with the -c
flag.
Required OpenAPI document to generate a client for.
Example:
document: ./openapi.yaml
The package path and optional name to use in the generated code.
Example:
package:
path: github.com/jbowes/go-sample
name: sample
Optional mapping of definitions to types.
Example:
types:
SomeDefinedType: github.com/org/package.TypeName
An optional map of OpenAPI format
values to Go types. Schema fields, array
items, and parameters that have these formats will be represented in the
generated code with the provided type.
Any types used here must implement the TextMarshaler interface.
Example:
string_formats:
telephone: github.com/org/package.TelephoneNumber
An optional override for the default output file.
Example:
output: zz_oag_generated_client_file.go
A niche configuration directive, allowing you to disable parts of oag
's code
generation, particularly for shipping generated code for multiple OpenAPI
documents in the same package.
Example:
boilerplate:
base_url: disabled
backend: disabled
endpoint: disabled
client_prefix: PutThisBeforeTypeNames
Introduction | Examples | Usage | Configuration | Contributing | License
I would love your help!
oag
is still a work in progress. You can help by:
- Trying
oag
against different OpenAPI documents, and reporting bugs when the generated code is broken, or suggesting improvements to the generated code. - Opening a pull request to resolve an open issue.
- Adding a feature or enhancement of your own! If it might be big, please open an issue first so we can discuss it.
- Improving this
README
or adding other documentation tooag
. - Letting me know if you're using
oag
.
Introduction | Examples | Usage | Configuration | Contributing | License
MIT License
Copyright (c) 2017 James Bowes
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.