Skip to content

Commit

Permalink
Merge pull request #234 from ogen-go/docs/update
Browse files Browse the repository at this point in the history
docs: add `Config` page
  • Loading branch information
tdakkota authored Oct 13, 2024
2 parents 76ab7c9 + 235e71b commit 6b3aa5b
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 52 deletions.
35 changes: 35 additions & 0 deletions docs/07-config.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
id: config
title: Config
sidebar_label: Config
sidebar_position: 7
---

ogen could be configurated via `.ogen.yml` file:

```yaml [title=".ogen.yml"]
# sets generator options.
generator:
# sets generator features.
features:
enable:
# Enables paths client generation
- "paths/client"
# Enables paths server generation
- "paths/server"
# Enables validation of client requests
- "client/request/validation"
# Enables validation of server responses
- "server/response/validation"
# Enables OpenTelemetry integration
- "ogen/otel"
disable_all: true
```
See full config example [here](https://github.com/ogen-go/ogen/blob/main/examples/_config/example_all.yml).
### Features
ogen provides a opt-in/opt-out mechanism for some features like OpenTelemetry integration.
You can find a [complete feature list](https://github.com/ogen-go/ogen/blob/main/gen/features.go) in ogen repository.
121 changes: 74 additions & 47 deletions docs/07-faq.mdx → docs/08-faq.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
id: faq
title: Frequently Asked Questions (FAQ)
sidebar_label: FAQ
sidebar_position: 7
sidebar_position: 8
---

### How to set `404 Not Found` handler?
Expand Down Expand Up @@ -116,75 +116,102 @@ func newServer() *http.Server {

See [Static router](concepts/static_router.mdx#using-nethttp-middlewares) section for more details.

### How to use prometheus?
### How to use Prometheus?

To instrument server or client with OpenTelemetry and prometheus exporter, pass `oas.Option`:
See [OpenTelemetry Go SDK examples](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/c3c853808383d1bce596cbb910546c305c9187e8/examples/prometheus/main.go#L33-L38).

Also, see [our `autometer` helper](https://pkg.go.dev/github.com/go-faster/sdk/autometer).

Example setup:

```go
package main

import (
"github.com/go-faster/errors"
promClient "github.com/prometheus/client_golang/prometheus"
"go.opentelemetry.io/otel/exporters/prometheus"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
controller "go.opentelemetry.io/otel/sdk/metric/controller/basic"
processor "go.opentelemetry.io/otel/sdk/metric/processor/basic"
selector "go.opentelemetry.io/otel/sdk/metric/selector/simple"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
"context"

"example/internal/oas"

"application/oas"
"github.com/prometheus/client_golang/prometheus"
otelprometheus "go.opentelemetry.io/otel/exporters/prometheus"
"go.opentelemetry.io/otel/metric"
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
)

// Resource returns new resource for application.
func Resource(name string) *resource.Resource {
r, _ := resource.Merge(
const appName = "my-ogen-service"

// setupMeterProvider setups Prometheus instrumentation.
func setupMeterProvider(reg prometheus.Registerer) (metric.MeterProvider, ShutdownFunc, error) {
// Create an OpenTelemetry Resource description.
//
// See https://opentelemetry.io/docs/languages/go/resources/
appResource, err := resource.Merge(
resource.Default(),
resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String(name),
semconv.ServiceNameKey.String(appName),
),
)
return r
}
if err != nil {
return nil, nil, err
}

func newPrometheus(config prometheus.Config, options ...controller.Option) (*prometheus.Exporter, error) {
c := controller.New(
processor.NewFactory(
selector.NewWithHistogramDistribution(
histogram.WithExplicitBoundaries(config.DefaultHistogramBoundaries),
),
aggregation.CumulativeTemporalitySelector(),
processor.WithMemory(true),
),
options...,
// Create Prometheus exporter and given registerer.
exp, err := otelprometheus.New(
otelprometheus.WithRegisterer(reg),
)
return prometheus.New(config, c)
}
if err != nil {
return nil, nil, err
}

// newMeterProviderOption returns oas.Option for prometheus instrumentation.
func newMeterProviderOption() (oas.Option, error) {
registry := promClient.NewPedanticRegistry()
res := Resource("app")
promExporter, err := newPrometheus(prometheus.Config{
DefaultHistogramBoundaries: promClient.DefBuckets,

Registry: registry,
Gatherer: registry,
Registerer: registry,
},
controller.WithCollectPeriod(0),
controller.WithResource(res),
mp := sdkmetric.NewMeterProvider(
sdkmetric.WithResource(appResource),
sdkmetric.WithReader(exp),
)
return mp, func(ctx context.Context) error {
// Flush collected metrics.
_ = mp.ForceFlush(ctx)
return mp.Shutdown(ctx)
}, nil
}

type ShutdownFunc = func(ctx context.Context) error

func createAPIServer(h oas.Handler) (_ *oas.Server, _ ShutdownFunc, rerr error) {
meterProvider, shutdown, err := setupMeterProvider(prometheus.DefaultRegisterer)
if err != nil {
return nil, nil, err
}
defer func() {
// Shutdown MeterProvider and release resources in case of error.
if rerr != nil {
shutdown(context.TODO())
}
}()

server, err := oas.NewServer(h, oas.WithMeterProvider(meterProvider))
if err != nil {
return nil, errors.Wrap(err, "prometheus")
return nil, nil, err
}
return oas.WithMeterProvider(promExporter.MeterProvider()), nil

// Returned `shutdown` function would stop metric collection.
return server, shutdown, nil
}
```

### How to add some tags to generated structures?

[Use `x-oapi-codegen-extra-tags` extension.](spec/extensions.md#extra-struct-field-tags)

### How to disable OpenTelemetry integration?

Disable `ogen/otel` feature via [config](config):

```yaml [title=".ogen.yml"]
generator:
features:
disable:
- "ogen/otel"
```
14 changes: 9 additions & 5 deletions docs/concepts/convenient_errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ If spec meets all following requirements:
then `ogen` generates special handler for errors returned by `Handler` implementation and does not generate default response variant.

For example:

```yaml
openapi: 3.0.3
info:
Expand Down Expand Up @@ -87,9 +88,12 @@ type Handler interface {

### Force or Disable `Convenient errors`

Use `--convenient-errors` option

- `auto` (default) generates `NewError` if possible
- `on` tells generator to fail if spec does not meet requirements
- `off` disables `Convenient errors` at all
Use `generator.convenient_errors` option

```yaml
generator:
# `auto` (default) generates `NewError` if possible
# `on` tells generator to fail if spec does not meet requirements
# `off` disables `Convenient errors` at all
convenient_errors: "auto"
```
78 changes: 78 additions & 0 deletions docs/spec/extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,37 @@ Optionally, type name can be specified by `x-ogen-name`, for example:
}
```

### Custom field name

Optionally, type name can be specified by `x-ogen-properties`, for example:

```yaml
components:
schemas:
Node:
type: object
properties:
parent:
$ref: "#/components/schemas/Node"
child:
$ref: "#/components/schemas/Node"
x-ogen-properties:
parent:
name: "Prev"
child:
name: "Next"
```
The generated source code looks like:
```go
// Ref: #/components/schemas/Node
type Node struct {
Prev *Node `json:"parent"`
Next *Node `json:"child"`
}
```

### Extra struct field tags

Optionally, additional Go struct field tags can be specified by `x-oapi-codegen-extra-tags`, for example:
Expand Down Expand Up @@ -151,3 +182,50 @@ requestBody:
items:
type: number
```
### Operation groups
Optionally, operations can be grouped so a handler interface will be generated for each group of operations.
This is useful for organizing operations for large APIs.
The group for operations on a path or individual operations can be specified by `x-ogen-operation-group`, for example:

```yaml
paths:
/images:
x-ogen-operation-group: Images
get:
operationId: listImages
...
/images/{imageID}:
x-ogen-operation-group: Images
get:
operationId: getImageByID
...
/users:
x-ogen-operation-group: Users
get:
operationId: listUsers
...
```

The generated handler interfaces look like this:

```go
// x-ogen-operation-group: Images
type ImagesHandler interface {
ListImages(ctx context.Context, req *ListImagesRequest) (*ListImagesResponse, error)
GetImageByID(ctx context.Context, req *GetImagesByIDRequest) (*GetImagesByIDResponse, error)
}
// x-ogen-operation-group: Users
type UsersHandler interface {
ListUsers(ctx context.Context, req *ListUsersRequest) (*ListUsersResponse, error)
}
type Handler interface {
ImagesHandler
UsersHandler
// All un-grouped operations will be on this interface
}
```

0 comments on commit 6b3aa5b

Please sign in to comment.