# Swag [](https://github.com/go-openapi/swag/actions?query=workflow%3A"go+test") [](https://codecov.io/gh/go-openapi/swag)
[](https://slackin.goswagger.io)
[](https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE)
[](https://pkg.go.dev/github.com/go-openapi/swag)
[](https://goreportcard.com/report/github.com/go-openapi/swag)
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](#contents)
* [Dependencies](#dependencies)
* [Release Notes](#release-notes)
* [Licensing](#licensing)
* [Note to contributors](#note-to-contributors)
* [TODOs, suggestions and plans](#todos-suggestions-and-plans)
## 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.4
** mangling**
Bug fix
* [x] mangler may panic with pluralized overlapping initialisms
Tests
* [x] introduced fuzz tests
### v0.25.3
** mangling**
Bug fix
* [x] mangler may panic with pluralized initialisms
### v0.25.2
Minor changes due to internal maintenance that don't affect the behavior of the library.
* [x] removed indirect test dependencies by switching all tests to `go-openapi/testify`,
a fork of `stretch/testify` with zero-dependencies.
* [x] improvements to CI to catch test reports.
* [x] modernized licensing annotations in source code, using the more compact SPDX annotations
rather than the full license terms.
* [x] simplified a bit JSON & YAML testing by using newly available assertions
* started the journey to an OpenSSF score card badge:
* [x] explicited permissions in CI workflows
* [x] published security policy
* pinned dependencies to github actions
* introduced fuzzing in tests
### 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 preferred 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](./jsonutils/adapters/testintegration/benchmarks/README.md) 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`.
```go
import (
"github.com/go-openapi/swag/jsonutils/adapters"
easyjson "github.com/go-openapi/swag/jsonutils/adapters/easyjson/json"
)
func init() {
easyjson.Register(adapters.Registry)
}
```
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.
For more details, you may also look at our
[integration tests](jsonutils/adapters/testintegration/integration_suite_test.go#29).
### 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**:
* [x] type converters and pointer to value helpers now support generic types
* [x] 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.
* [x] performance: small improvements to reduce the overhead of convert/format wrappers (see issues #110, or PR #108)
* [x] performance: name mangling utilities run ~ 10% faster (PR #115)
---
## Licensing
This library ships under the [SPDX-License-Identifier: Apache-2.0](./LICENSE).
## 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:
* [x] Complete the split of dependencies to isolate easyjson from the rest
* [x] Improve CI to reduce needed tests
* [x] 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)