Skip to content

Commit db4bd1f

Browse files
chore(docs): clarify breaking changes (#306)
1 parent 66a3a67 commit db4bd1f

File tree

2 files changed

+78
-40
lines changed

2 files changed

+78
-40
lines changed

Diff for: MIGRATION.md

+72-38
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,39 @@
22

33
<a href="https://pkg.go.dev/github.com/openai/openai-go"><img src="https://pkg.go.dev/badge/github.com/openai/openai-go.svg" alt="Go Reference"></a>
44

5-
This SDK includes breaking changes from the previous version to improve the ergonomics of constructing parameters and accessing responses.
5+
This SDK includes breaking changes to improve the ergonomics of constructing parameters and accessing responses.
6+
7+
To reduce verbosity, the `openai.F(...)` and `param.Field[T]` have been removed.
8+
All calls to `openai.F(...)` can be deleted.
9+
10+
The SDK now uses the <code>\`json:"...,omitzero"\`</code> struct tag to omit fields. Nested structs, arrays and maps
11+
can be declared like normal.
12+
13+
The old SDK used interfaces for unions in requests, which required
14+
a type assertion to access variants and fields. The new design uses
15+
structs with a field for each variant, wherein only one field can be set.
16+
These struct unions also expose 'Get' methods to access and mutate subfields
17+
which may be shared by multiple variants.
618

719
# Request parameters
820

921
## Required primitives parameters serialize their zero values (`string`, `int64`, etc.)
1022

11-
> [!CAUTION] > **This change can cause new behavior in existing code, without compiler warnings.**
23+
> [!CAUTION]
24+
>
25+
> **This change can cause new behavior in existing code, without compiler warnings.**
26+
27+
While migrating, ensure that all required fields are explicitly set. A required primitive
28+
field `Age` will use the <code>\`json:"age,required"\`</code> struct tag without `omitzero`.
29+
30+
If a required primitive field is not set, the zero value will be serialized.
31+
This was not the case in with `param.Field[T]`.
1232

1333
```diff
1434
type FooParams struct {
1535
- Age param.Field[int64] `json:"age,required"`
1636
- Name param.Field[string] `json:"name"`
17-
+ Age int64 `json:"age,required"`
37+
+ Age int64 `json:"age,required"` // <== Notice no omitzero
1838
+ Name param.Opt[string] `json:"name,omitzero"`
1939
}
2040
```
@@ -48,43 +68,24 @@ _ = FooParams{
4868
</tr>
4969
</table>
5070

51-
The required field `"age"` is now present as `0`. Required primitive fields without the <code>\`json:"...,omitzero"\`</code> struct tag
71+
The required field `"age"` is now present as `0`. Fields without the <code>\`json:"...,omitzero"\`</code> struct tag
5272
are always serialized, including their zero values.
5373

5474
## Transition from `param.Field[T]` to `omitzero`
5575

56-
The new SDK uses <a href="https://pkg.go.dev/encoding/json#Marshal"><code>\`json:"...,omitzero"\`</code> semantics</a> from Go 1.24+ for JSON encoding[^1].
57-
58-
`omitzero` is used for structs, slices, maps, string enums, and optional primitive types wrapped in `param.Opt[T]` (e.g. `param.Opt[string]`).
59-
60-
**Fields of a request struct:**
61-
62-
```diff
63-
type FooParams struct {
64-
- RequiredString param.Field[string] `json:"required_string,required"`
65-
+ RequiredString string `json:"required_string,required"`
66-
67-
- OptionalString param.Field[string] `json:"optional_string"`
68-
+ OptionalString param.Opt[string] `json:"optional_string,omitzero"`
69-
70-
- Array param.Field[[]BarParam] `json"array"`
71-
+ Array []BarParam `json"array,omitzero"`
76+
The `openai.F(...)` function and `param.Field[T]` type are no longer present in the new SDK.
7277

73-
- Map param.Field[map[string]BarParam] `json"map"`
74-
+ Map map[string]BarParam `json"map,omitzero"`
78+
To represent omitted fields, the SDK uses <a href="https://pkg.go.dev/encoding/json#Marshal"><code>\`json:"...,omitzero"\`</code> semantics</a> from Go 1.24+ for JSON encoding[^1]. `omitzero` always omits fields
79+
with zero values.
7580

76-
- RequiredObject param.Field[BarParam] `json:"required_object,required"`
77-
+ RequiredObject BarParam `json:"required_object,omitzero,required"`
81+
In all cases other than optional primitives, `openai.F()` can simply be removed.
82+
For optional primitive types, such as `param.Opt[string]`, you can use `openai.String(string)` to construct the value.
83+
Similar functions exist for other primitive types like `openai.Int(int)`, `openai.Bool(bool)`, etc.
7884

79-
- OptionalObject param.Field[BarParam] `json:"optional_object"`
80-
+ OptionalObject BarParam `json:"optional_object,omitzero"`
85+
`omitzero` is used for fields whose type is either a struct, slice, map, string enum,
86+
or wrapped optional primitive (e.g. `param.Opt[T]`). Required primitive fields don't use `omitzero`.
8187

82-
- StringEnum param.Field[BazEnum] `json:"string_enum"`
83-
+ StringEnum BazEnum `json:"string_enum,omitzero"`
84-
}
85-
```
86-
87-
**Previous vs New SDK: Constructing a request**
88+
**Example User Code: Constructing a request**
8889

8990
```diff
9091
foo = FooParams{
@@ -112,12 +113,36 @@ foo = FooParams{
112113
}
113114
```
114115

115-
`param.Opt[string]` can be constructed with `openai.String(string)`. Similar functions exist for other primitive
116-
types like `openai.Int(int)`, `openai.Bool(bool)`, etc.
116+
**Internal SDK Code: Fields of a request struct:**
117+
118+
```diff
119+
type FooParams struct {
120+
- RequiredString param.Field[string] `json:"required_string,required"`
121+
+ RequiredString string `json:"required_string,required"`
122+
123+
- OptionalString param.Field[string] `json:"optional_string"`
124+
+ OptionalString param.Opt[string] `json:"optional_string,omitzero"`
125+
126+
- Array param.Field[[]BarParam] `json"array"`
127+
+ Array []BarParam `json"array,omitzero"`
128+
129+
- Map param.Field[map[string]BarParam] `json"map"`
130+
+ Map map[string]BarParam `json"map,omitzero"`
131+
132+
- RequiredObject param.Field[BarParam] `json:"required_object,required"`
133+
+ RequiredObject BarParam `json:"required_object,omitzero,required"`
134+
135+
- OptionalObject param.Field[BarParam] `json:"optional_object"`
136+
+ OptionalObject BarParam `json:"optional_object,omitzero"`
137+
138+
- StringEnum param.Field[BazEnum] `json:"string_enum"`
139+
+ StringEnum BazEnum `json:"string_enum,omitzero"`
140+
}
141+
```
117142

118143
## Request Unions: Removing interfaces and moving to structs
119144

120-
For a type `AnimalUnionParam` which could be either a `string | CatParam | DogParam`.
145+
For a type `AnimalUnionParam` which could be either a `CatParam | DogParam`.
121146

122147
<table>
123148
<tr><th>Previous</th> <th>New</th></tr>
@@ -237,14 +262,23 @@ The `.IsNull()` method has been changed to `.IsPresent()` to better reflect its
237262
```diff
238263
- if !resp.Foo.JSON.Bar.IsNull() {
239264
+ if resp.Foo.JSON.Bar.IsPresent() {
240-
println("bar is present:", resp.Foo.Bar)
241-
}
265+
println("bar is present:", resp.Foo.Bar)
266+
}
242267
```
243268

244269
| Previous | New | Returns true for values |
245270
| -------------- | ------------------- | ----------------------- |
246271
| `.IsNull()` | `!.IsPresent()` | `null` or Omitted |
247272
| `.IsMissing()` | `.Raw() == ""` | Omitted |
248-
| `.Invalid()` | `.IsExplicitNull()` | `null` |
273+
| | `.IsExplicitNull()` | `null` |
274+
275+
## Checking Raw JSON of a response
276+
277+
The `.RawJSON()` method has moved to the parent of the `.JSON` property.
278+
279+
```diff
280+
- resp.Foo.JSON.RawJSON()
281+
+ resp.Foo.RawJSON()
282+
```
249283

250284
[^1]: The SDK doesn't require Go 1.24, despite supporting the `omitzero` feature

Diff for: README.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
The OpenAI Go library provides convenient access to [the OpenAI REST
66
API](https://platform.openai.com/docs) from applications written in Go. The full API of this library can be found in [api.md](api.md).
77

8+
> [!WARNING]
9+
> The latest version of this package uses a new design with significant breaking changes.
10+
> Please refer to the [migration guide](./MIGRATION.md) for more information on how to update your code.
11+
812
## Installation
913

1014
<!-- x-release-please-start-version -->
@@ -342,8 +346,8 @@ Otherwise, the `param.IsOmitted(any)` function can confirm the presence of any `
342346
Unions are represented as a struct with fields prefixed by "Of" for each of it's variants,
343347
only one field can be non-zero. The non-zero field will be serialized.
344348

345-
Properties can be accessed via getters on the union struct. These getters return a mutable
346-
pointer to the underlying data, if present.
349+
Sub-properties of the union can be accessed via methods on the union struct.
350+
These methods return a mutable pointer to the underlying data, if present.
347351

348352
```go
349353
// Only one field can be non-zero, use param.IsOmitted() to check if a field is set

0 commit comments

Comments
 (0)