Skip to content

Commit

Permalink
Merge pull request #372 from danielgtaylor/cbor-optional
Browse files Browse the repository at this point in the history
fix: make cbor support optional
  • Loading branch information
danielgtaylor committed Apr 15, 2024
2 parents 808a95d + e55b175 commit 00fc8c3
Show file tree
Hide file tree
Showing 25 changed files with 149 additions and 55 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Features include:
- JSON Errors using [RFC9457](https://datatracker.ietf.org/doc/html/rfc9457) and `application/problem+json` by default (but can be changed)
- Per-operation request size limits with sane defaults
- [Content negotiation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation) between server and client
- Support for JSON ([RFC 8259](https://tools.ietf.org/html/rfc8259)) and CBOR ([RFC 7049](https://tools.ietf.org/html/rfc7049)) content types via the `Accept` header with the default config.
- Support for JSON ([RFC 8259](https://tools.ietf.org/html/rfc8259)) and optionally CBOR ([RFC 7049](https://tools.ietf.org/html/rfc7049)) content types via the `Accept` header with the default config.
- Conditional requests support, e.g. `If-Match` or `If-Unmodified-Since` header utilities.
- Optional automatic generation of `PATCH` operations that support:
- [RFC 7386](https://www.rfc-editor.org/rfc/rfc7386) JSON Merge Patch
Expand Down Expand Up @@ -104,6 +104,8 @@ import (
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// Options for the CLI. Pass `--port` or set the `SERVICE_PORT` env var.
Expand Down
63 changes: 23 additions & 40 deletions defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package huma
import (
"encoding/json"
"io"

"github.com/fxamacker/cbor/v2"
)

// DefaultJSONFormat is the default JSON formatter that can be set in the API's
Expand All @@ -22,46 +20,36 @@ var DefaultJSONFormat = Format{
Unmarshal: json.Unmarshal,
}

var cborEncMode, _ = cbor.EncOptions{
// Canonical enc opts
Sort: cbor.SortCanonical,
ShortestFloat: cbor.ShortestFloat16,
NaNConvert: cbor.NaNConvert7e00,
InfConvert: cbor.InfConvertFloat16,
IndefLength: cbor.IndefLengthForbidden,
// Time handling
Time: cbor.TimeUnixDynamic,
TimeTag: cbor.EncTagRequired,
}.EncMode()

// DefaultCBORFormat is the default CBOR formatter that can be set in the API's
// `Config.Formats` map. This is used by the `DefaultConfig` function.
// DefaultFormats is a map of default formats that can be set in the API's
// `Config.Formats` map, used for content negotiation for marshaling and
// unmarshaling request/response bodies. This is used by the `DefaultConfig`
// function and can be modified to add or remove additional formats. For
// example, to add support for CBOR, simply import it:
//
// config := huma.Config{}
// config.Formats = map[string]huma.Format{
// "application/cbor": huma.DefaultCBORFormat,
// "cbor": huma.DefaultCBORFormat,
// }
var DefaultCBORFormat = Format{
Marshal: func(w io.Writer, v any) error {
return cborEncMode.NewEncoder(w).Encode(v)
},
Unmarshal: cbor.Unmarshal,
// import _ "github.com/danielgtaylor/huma/v2/formats/cbor"
var DefaultFormats = map[string]Format{
"application/json": DefaultJSONFormat,
"json": DefaultJSONFormat,
}

// DefaultConfig returns a default configuration for a new API. It is a good
// starting point for creating your own configuration. It supports JSON and
// CBOR formats out of the box. The registry uses references for structs and
// a link transformer is included to add `$schema` fields and links into
// responses. The `/openapi.[json|yaml]`, `/docs`, and `/schemas` paths are
// set up to serve the OpenAPI spec, docs UI, and schemas respectively.
// starting point for creating your own configuration. It supports the JSON
// format out of the box. The registry uses references for structs and a link
// transformer is included to add `$schema` fields and links into responses. The
// `/openapi.[json|yaml]`, `/docs`, and `/schemas` paths are set up to serve the
// OpenAPI spec, docs UI, and schemas respectively.
//
// // Create and customize the config (if desired).
// config := huma.DefaultConfig("My API", "1.0.0")
//
// // Create the API using the config.
// router := chi.NewMux()
// api := humachi.New(router, config)
//
// If desired, CBOR (a binary format similar to JSON) support can be
// automatically enabled by importing the CBOR package:
//
// import _ "github.com/danielgtaylor/huma/v2/formats/cbor"
func DefaultConfig(title, version string) Config {
schemaPrefix := "#/components/schemas/"
schemasPath := "/schemas"
Expand All @@ -79,15 +67,10 @@ func DefaultConfig(title, version string) Config {
Schemas: registry,
},
},
OpenAPIPath: "/openapi",
DocsPath: "/docs",
SchemasPath: schemasPath,
Formats: map[string]Format{
"application/json": DefaultJSONFormat,
"json": DefaultJSONFormat,
"application/cbor": DefaultCBORFormat,
"cbor": DefaultCBORFormat,
},
OpenAPIPath: "/openapi",
DocsPath: "/docs",
SchemasPath: schemasPath,
Formats: DefaultFormats,
DefaultFormat: "application/json",
CreateHooks: []func(Config) Config{
func(c Config) Config {
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/features/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Features include:
- JSON Errors using [RFC9457](https://tools.ietf.org/html/rfc9457) and `application/problem+json` by default (but can be changed)
- Per-operation request size limits with sane defaults
- [Content negotiation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation) between server and client
- Support for JSON ([RFC 8259](https://tools.ietf.org/html/rfc8259)) and CBOR ([RFC 7049](https://tools.ietf.org/html/rfc7049)) content types via the `Accept` header with the default config.
- Support for JSON ([RFC 8259](https://tools.ietf.org/html/rfc8259)) and optional CBOR ([RFC 7049](https://tools.ietf.org/html/rfc7049)) content types via the `Accept` header with the default config.
- Conditional requests support, e.g. `If-Match` or `If-Unmodified-Since` header utilities.
- Optional automatic generation of `PATCH` operations that support:
- [RFC 7386](https://www.rfc-editor.org/rfc/rfc7386) JSON Merge Patch
Expand Down
15 changes: 14 additions & 1 deletion docs/docs/features/response-serialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,23 @@ When handler functions return Go objects, they will be serialized to bytes for t

The [`config.Formats`](https://pkg.go.dev/github.com/danielgtaylor/huma/v2#Config) maps either a content type name or extension (suffix) to a `huma.Format` instance.

The default configuration for Huma includes support for JSON ([RFC 8259](https://tools.ietf.org/html/rfc8259)) and CBOR ([RFC 7049](https://tools.ietf.org/html/rfc7049)) content types via the `Accept` header. This is done by registering the following content types using [`huma.DefaultJSONFormat`](https://pkg.go.dev/github.com/danielgtaylor/huma/v2#DefaultJSONFormat) & [`huma.DefaultCBORFormat`](https://pkg.go.dev/github.com/danielgtaylor/huma/v2#DefaultCBORFormat):
The default configuration for Huma includes support for JSON ([RFC 8259](https://tools.ietf.org/html/rfc8259)) and optionally CBOR ([RFC 7049](https://tools.ietf.org/html/rfc7049)) content types via the `Accept` header. This is done by registering the following content types using [`huma.DefaultJSONFormat`](https://pkg.go.dev/github.com/danielgtaylor/huma/v2#DefaultJSONFormat):

- `application/json`
- Anything ending with `+json`

CBOR support can be enabled by importing the `cbor` package, which adds [`cbor.DefaultCBORFormat`](https://pkg.go.dev/github.com/danielgtaylor/huma/v2/formats/cbor#DefaultCBORFormat) to the default list of formats:

```go title="main.go"
import (
"github.com/danielgtaylor/huma/v2"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)
```

This adds the following content types:

- `application/cbor`
- Anything ending with `+cbor`

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/how-to/graceful-shutdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This can be accomplished in Huma using the CLI `hooks.OnStop()` hook, passing a

## Example

```go title="code.go" linenums="1" hl_lines="6-7 50-67"
```go title="code.go" linenums="1" hl_lines="6-7 51-68"
package main

import (
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/how-to/image-response.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Images or other encoded or binary responses can be returned by simply using a `[

## Example

```go title="code.go" linenums="1" hl_lines="18-22 31-50"
```go title="code.go" linenums="1" hl_lines="19-23 32-51"
package main

import (
Expand Down
3 changes: 1 addition & 2 deletions docs/docs/terminal/install.cast
Original file line number Diff line number Diff line change
Expand Up @@ -191,5 +191,4 @@
[9.540756, "o", "v"]
[9.580533, "o", "2"]
[9.621607, "o", "\r\n\u001b[0m"]
[9.860282, "o", "go: added github.com/danielgtaylor/casing v0.0.0-20210126043903-4e55e6373ac3\r\n\u001b[0mgo: added github.com/danielgtaylor/huma/v2 v2.0.0-beta.3\r\n\u001b[0mgo: added github.com/danielgtaylor/mexpr v1.8.0\r\n...\r\n\u001b[0mgo: added gopkg.in/ini.v1 v1.67.0\r\n\u001b[0mgo: added gopkg.in/yaml.v3 v3.0.1\r\n\u001b[0m"]

[9.860282, "o", "...\r\n\u001b[0m"]
4 changes: 3 additions & 1 deletion docs/docs/tutorial/client-sdks.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ description: Level up your API with a generated Go SDK and client that uses it.

First, let's create a command to grab the OpenAPI spec so the service doesn't need to be running and you can generate the SDK as needed (e.g. as part of the API service release process).

```go title="main.go" linenums="1" hl_lines="67 73 84-94"
```go title="main.go" linenums="1" hl_lines="69 75 86-96"
package main

import (
Expand All @@ -22,6 +22,8 @@ import (
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// Options for the CLI.
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/tutorial/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Huma requires [Go 1.20 or newer](https://go.dev/dl/), so install that first. You

Next, open a terminal and create a new Go project, then go get the Huma dependency to it's ready to be imported:

{{ asciinema("../../terminal/install.cast", rows="18") }}
{{ asciinema("../../terminal/install.cast", rows="12") }}

You should now have a directory structure like this:

Expand Down
4 changes: 3 additions & 1 deletion docs/docs/tutorial/sending-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Response: 201 Created

Add a new operation to our API that allows users to submit reviews of our product.

```go title="main.go" linenums="1" hl_lines="25-32 57-68"
```go title="main.go" linenums="1" hl_lines="28-35 60-71"
package main

import (
Expand All @@ -34,6 +34,8 @@ import (
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// Options for the CLI.
Expand Down
4 changes: 3 additions & 1 deletion docs/docs/tutorial/service-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Huma includes a basic command-line and environment variable option parser that c

[Your first API](your-first-api.md#operation) can be updated to take an optional network port parameter like this:

```go title="main.go" linenums="1" hl_lines="13-16 26-27 48-56"
```go title="main.go" linenums="1" hl_lines="16-19 29-30 51-59"
package main

import (
Expand All @@ -22,6 +22,8 @@ import (
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// Options for the CLI.
Expand Down
4 changes: 3 additions & 1 deletion docs/docs/tutorial/writing-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Huma provides a number of helpers for testing your API. The most important is th

First, modify the service code to make it easier to test, by moving the operation registration code out of the `main` function:

```go title="main.go" linenums="1" hl_lines="34 63 72"
```go title="main.go" linenums="1" hl_lines="37 66 75"
package main

import (
Expand All @@ -22,6 +22,8 @@ import (
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// Options for the CLI.
Expand Down
12 changes: 9 additions & 3 deletions docs/docs/tutorial/your-first-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ my-api/

Let's create a router, which will handle getting incoming requests to the correct operation handler, and a new API instance where we can register our operation.

```go title="main.go" linenums="1" hl_lines="3-9 18-27"
```go title="main.go" linenums="1" hl_lines="3-11 20-29"
package main

import (
Expand All @@ -57,6 +57,8 @@ import (
"github.com/danielgtaylor/huma/v2"
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// GreetingOutput represents the greeting operation response.
Expand Down Expand Up @@ -93,7 +95,7 @@ func main() {

Register the operation with the Huma API instance, including how it maps to a URL. The handler function will take in a struct that defines its inputs (in this case a path parameter named `name`) and return the `GreetingOutput` model we built above.

```go title="main.go" linenums="1" hl_lines="4-5 25-32"
```go title="main.go" linenums="1" hl_lines="4-5 27-34"
package main

import (
Expand All @@ -104,6 +106,8 @@ import (
"github.com/danielgtaylor/huma/v2"
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// GreetingOutput represents the greeting operation response.
Expand Down Expand Up @@ -180,7 +184,7 @@ These docs are generated from the OpenAPI specification. You can use this file t

You can use `huma.Register` to add more information to the OpenAPI specification, such as descriptions with Markdown, examples, tags, and more. The `huma.Operation` struct provides full access to the OpenAPI including the ability to add extensions. See the [`huma.Operation`](https://pkg.go.dev/github.com/danielgtaylor/huma/v2#Operation) struct for more details.

```go title="main.go" linenums="1" hl_lines="26-33"
```go title="main.go" linenums="1" hl_lines="28-35"
package main

import (
Expand All @@ -191,6 +195,8 @@ import (
"github.com/danielgtaylor/huma/v2"
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// GreetingOutput represents the greeting operation response.
Expand Down
2 changes: 2 additions & 0 deletions examples/cookies/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// Options for the CLI.
Expand Down
2 changes: 2 additions & 0 deletions examples/custom-error/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"github.com/danielgtaylor/huma/v2"
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

type MyError struct {
Expand Down
2 changes: 2 additions & 0 deletions examples/greet/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// Options for the CLI.
Expand Down
2 changes: 2 additions & 0 deletions examples/omit/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// Options for the CLI.
Expand Down
2 changes: 2 additions & 0 deletions examples/oneof-response/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// Options for the CLI.
Expand Down
2 changes: 2 additions & 0 deletions examples/param-reuse/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// Options for the CLI.
Expand Down
2 changes: 2 additions & 0 deletions examples/resolver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import (
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// Options for the CLI.
Expand Down
2 changes: 2 additions & 0 deletions examples/spec-cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi/v5"
"github.com/spf13/cobra"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// Options for the CLI.
Expand Down
2 changes: 2 additions & 0 deletions examples/sse/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/danielgtaylor/huma/v2/sse"
"github.com/go-chi/chi/v5"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// Options for the CLI.
Expand Down
2 changes: 2 additions & 0 deletions examples/v1-middleware/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"github.com/danielgtaylor/huma/v2/adapters/humachi"
"github.com/danielgtaylor/huma/v2/humacli"
"github.com/go-chi/chi"

_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// Options for the CLI.
Expand Down
Loading

0 comments on commit 00fc8c3

Please sign in to comment.