Skip to content

go-openapi/swag

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Swag Build Status codecov

Slack Status license Go Reference Go Report Card

Package swag contains a bunch of helper functions for go-openapi and go-swagger projects.

You may also use it standalone for your projects.

NOTE swag is one of the foundational building blocks of the go-openapi initiative. Most repositories in github.com/go-openapi/... depend on it in some way. And so does our CLI tool github.com/go-swagger/go-swagger, as well as the code generated by this tool.

Contents

go-openapi/swag exposes a collection of relatively independent modules.

Moving forward, no additional feature will be added to the swag API directly at the root package level, which remains there for backward-compatibility purposes. All exported top-level features are now deprecated.

Child modules will continue to evolve and some new ones may be added in the future.

Module Content Main features
cmdutils utilities to work with CLIs
conv type conversion utilities convert between values and pointers for any types
convert from string to builtin types (wraps strconv)
require ./typeutils (test dependency)
fileutils file utilities
jsonname JSON utilities infer JSON names from go properties
jsonutils JSON utilities fast json concatenation
read and write JSON from and to dynamic go data structures
require github.com/mailru/easyjson
loading file loading load from file or http
require ./yamlutils
mangling safe name generation name mangling for go
netutils networking utilities host, port from address
stringutils string utilities search in slice (with case-insensitive)
split/join query parameters as arrays
typeutils go types utilities check the zero value for any type
safe check for a nil value
yamlutils YAML utilities converting YAML to JSON
loading YAML into a dynamic YAML document
maintaining the original order of keys in YAML objects
require ./jsonutils
require github.com/mailru/easyjson
require go.yaml.in/yaml/v3

Dependencies

The root module github.com/go-openapi/swag at the repo level maintains a few dependencies outside of the standard library.

  • YAML utilities depend on go.yaml.in/yaml/v3
  • JSON utilities depend on their registered adapter module:
    • by default, only the standard library is used
    • github.com/mailru/easyjson is now only a dependency for module github.com/go-openapi/swag/jsonutils/adapters/easyjson/json, for users willing to import that module.
    • integration tests and benchmarks use all the dependencies are published as their own module
  • other dependencies are test dependencies drawn from github.com/stretchr/testify

Release notes

v0.25.1

  • fixes a data race that could occur when using the standard library implementation of a JSON ordered map

v0.25.0

New with this release:

  • requires go1.24, as iterators are being introduced
  • removes the dependency to mailru/easyjson by default (#68)
    • functionality remains the same, but performance may somewhat degrade for applications that relied on easyjson
    • users of the JSON or YAML utilities who want to use easyjson as their prefered JSON serializer library will be able to do so by registering this the corresponding JSON adapter at runtime. See below.
    • ordered keys in JSON and YAML objects: this feature used to rely solely on easyjson. With this release, an implementation relying on the standard encoding/json is provided.
    • an independent benchmark to compare the different adapters
  • improves the "float is integer" check (conv.IsFloat64AJSONInteger) (#59)
  • removes the direct dependency to gopkg.in/yaml.v3 (indirect dependency is still incurred through stretchr/testify) (#127)
  • exposed conv.IsNil() (previously kept private): a safe nil check (accounting for the "non-nil interface with nil value" nonsensical go trick)

What coming next?

Moving forward, we want to :

  • provide an implementation of the JSON adapter based on encoding/json/v2, for go1.25 builds.
  • provide similar implementations for goccy/go-json and jsoniterator/go, and perhaps some other similar libraries may be interesting too.

How to explicitly register a dependency at runtime?

The following would maintain how JSON utilities proposed by swag used work, up to v0.24.1.

import "github.com/go-openapi/swag/jsonutils/adapters/easyjson/json"

func init() {
  json.Register()
}

Subsequent calls to jsonutils.ReadJSON() or jsonutils.WriteJSON() will switch to easyjson whenever the passed data structures implement the easyjson.Unmarshaler or easyjson.Marshaler respectively, or fallback to the standard library.

v0.24.0

With this release, we have largely modernized the API of swag:

  • The traditional swag API is still supported: code that imports swag will still compile and work the same.
  • A deprecation notice is published to encourage consumers of this library to adopt the newer API
  • Deprecation notice
    • configuration through global variables is now deprecated, in favor of options passed as parameters
    • all helper functions are moved to more specialized packages, which are exposed as go modules. Importing such a module would reduce the footprint of dependencies.
    • all functions, variables, constants exposed by the deprecated API have now moved, so that consumers of the new API no longer need to import github.com/go-openapi/swag, but should import the desired sub-module(s).

New with this release:

  • type converters and pointer to value helpers now support generic types
  • name mangling now support pluralized initialisms (issue #46) Strings like "contact IDs" are now recognized as such a plural form and mangled as a linter would expect.
  • performance: small improvements to reduce the overhead of convert/format wrappers (see issues #110, or PR #108)
  • performance: name mangling utilities run ~ 10% faster (PR #115)

Note to contributors

A mono-repo structure comes with some unavoidable extra pains...

  • Testing

The usual go test ./... command, run from the root of this repo won't work any longer to test all submodules.

Each module constitutes an independant unit of test. So you have to run go test inside each module. Or you may take a look at how this is achieved by CI [here] https://github.com/go-openapi/swag/blob/master/.github/workflows/go-test.yml).

There are also some alternative tricks using go work, for local development, if you feel comfortable with go workspaces. Perhaps some day, we'll have a go work test to run all tests without any hack.

  • Releasing

Each module follows its own independant module versioning.

So you have tags like mangling/v0.24.0, fileutils/v0.24.0 etc that are used by go mod and go get to refer to the tagged version of each module specifically.

This means we may release patches etc to each module independently.

We'd like to adopt the rule that modules in this repo would only differ by a patch version (e.g. v0.24.5 vs v0.24.3), and we'll level all modules whenever a minor version is introduced.

A script in ./hack is provided to tag all modules with the same version in one go.

  • Continuous integration

At this moment, all tests in all modules are systematically run over the full test matrix (3 platform x 2 go releases). This generates quite a lot of jobs.

We ought to reduce the number of jobs required to test a PR focused on only a few modules.

Todos, suggestions and plans

All kinds of contributions are welcome.

A few ideas:

  • Complete the split of dependencies to isolate easyjson from the rest
  • Improve CI to reduce needed tests
  • Replace dependency to gopkg.in/yaml.v3 (yamlutil)
  • Improve mangling utilities (improve readability, support for capitalized words, better word substitution for non-letter symbols...)
  • Move back to this common shared pot a few of the technical features introduced by go-swagger independently (e.g. mangle go package names, search package with go modules support, ...)
  • Apply a similar mono-repo approach to go-openapi/strfmt which suffer from similar woes: bloated API, imposed dependency to some database driver.
  • Adapt go-swagger (incl. generated code) to the new swag API.
  • Factorize some tests, as there is a lot of redundant testing code in jsonutils
  • Benchmark & profiling: publish independently the tool built to analyze and chart benchmarks (e.g. similar to benchvisual)
  • more thorough testing for nil / null case
  • ci pipeline to manage releases
  • cleaner mockery generation (doesn't work out of the box for all sub-modules)