Skip to main content

Go Design

The Go SDKs are designed to be easy to use and easy to debug. Various decisions were made that guide the design of the SDK, these include:

  • Minimal dependencies and relying on the Go standard library as much as possible.
  • Struct tags and reflection based (de)serializers to define how the types we generate are correctly serialized based on the OpenAPI document.
  • Pointers for optional objects including fields/parameters/response and request bodies to ensure that the user can differentiate between a field not being set and a field being set to a zero value.
  • A Utils package that improves readability by bundling the methods for configuring the SDK and serializing/deserializing the types we generate into a shared package, avoiding the need to duplicate in each method.



For Go SDKs to be easy to use and minimize the time to 200, they need to reduce the opportunity for users to send requests that don't match the API spec. To that end, the Go SDKs that we generate convey maximal information to the end-user, and where possible, actively restrict inputs.

Here's the Pet model generated by Swagger CodeGen using Swagger's Petstore OpenAPI schema:

package swagger

type Pet struct {
Id int64 `json:"id,omitempty"`
Name string `json:"name"`
Category *Category `json:"category,omitempty"`
PhotoUrls []string `json:"photoUrls"`
Tags []Tag `json:"tags,omitempty"`
// pet status in the store
Status string `json:"status,omitempty"`
  • Required parameters are differentiated from optional parameters only by the presence of the omitempty annotation.
  • Status is represented as a string, despite it having only three valid values (available, pending, and sold) in the openapi spec.

And here's the Pet model generated by Speakeasy:

package shared

type PetStatusEnum string

const (
PetStatusEnumAvailable PetStatusEnum = "available"
PetStatusEnumPending PetStatusEnum = "pending"
PetStatusEnumSold PetStatusEnum = "sold"

type Pet struct {
Category *Category `json:"category,omitempty"`
ID *int64 `json:"id,omitempty"`
Name string `json:"name"`
PhotoUrls []string `json:"photoUrls"`
Status *PetStatusEnum `json:"status,omitempty"`
Tags []Tag `json:"tags,omitempty"`
  • Optional parameters are indicated by pointers, which permits them to evaluate as nil. That is especially useful when the model is received as the response from an api-call, as it allows the user to distinguish between unset (nil) and the default.
  • Status is now an enum, guiding users to provide one of the three permissible values.


Communicating authorization methods can be difficult, especially when there are multiple methods of authenticating or different styles of authorization for different endpoints. Swagger's Petstore OpenAPI schema uses multiple types of authentication and different authentication schemes for different endpoints.

Here's an example of how Speakeasy handles a request with a specific authentication scheme:

package operations

type FindPetsByStatusStatusEnum string

// ...

type FindPetsByStatusQueryParams struct {
Status *FindPetsByStatusStatusEnum `queryParam:"style=form,explode=true,name=status"`

type FindPetsByStatusSecurity struct {
PetstoreAuth shared.SchemePetstoreAuth `security:"scheme,type=oauth2"`

type FindPetsByStatusRequest struct {
QueryParams FindPetsByStatusQueryParams
Security FindPetsByStatusSecurity

type FindPetsByStatusResponse struct {
Body []byte
ContentType string
Pets []shared.Pet
StatusCode int64

Importantly, the exact type of authentication required (shared.SchemePetstoreAuth) is specified in the request.

Compare that to the code generated by Swagger CodeGen:

type PetApiFindPetsByStatusOpts struct {
Status optional.String

Security must be set through the Context passed in to the FindPetsByStatus method, and nowhere is it communicated what style of authentication is required for each endpoint.

If you have any feedback or want to suggest improvements or ask for a new feature please get in contact in the #client-sdks channel in our public Slack.