Skip to content

Commit f718c15

Browse files
authored
feat(docs): usage with sqlc and oapi-codegen (#79)
1 parent 5e8c5b6 commit f718c15

1 file changed

Lines changed: 142 additions & 0 deletions

File tree

README.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,148 @@ ID types in this package can be used with [database/sql](https://pkg.go.dev/data
5656

5757
When using the standard library SQL, IDs will be stored as their string representation and can be scanned and valued accordingly. When using pgx, both TEXT and UUID columns can be used directly. However, note that the type information is lost when using UUID columns, unless you take additional steps at the database layer. Be mindful of your identifier semantics, especially in complex JOIN queries.
5858

59+
If using `pgx` with PostgreSQL, you can generate UUIDv4 (for usage with `typeid.Random`) as the default value for your primary key:
60+
61+
```sql
62+
CREATE TABLE users (
63+
id UUID PRIMARY KEY DEFAULT GEN_RANDOM_UUID(),
64+
...
65+
);
66+
```
67+
68+
For k-sortable TypeIDs (`typeid.Sortable`, using UUIDv7) you will have to generate the UUID in your application unless you are running [PostgreSQL 18](https://www.thenile.dev/blog/uuidv7) or new where both are supported:
69+
70+
```sql
71+
-- With random TypeID
72+
CREATE TABLE users (
73+
id UUID PRIMARY KEY DEFAULT uuidv4(),
74+
...
75+
);
76+
77+
-- With sortable TypeID
78+
CREATE TABLE users (
79+
id UUID PRIMARY KEY DEFAULT uuidv7(),
80+
...
81+
);
82+
```
83+
84+
## Using with sqlc
85+
86+
TypeIDs work seamlessly with [sqlc](https://sqlc.dev/) by using column overrides in your `sqlc.yaml` configuration:
87+
88+
```yaml
89+
version: "2"
90+
sql:
91+
- schema: "schema.sql"
92+
queries: "queries"
93+
engine: postgresql
94+
gen:
95+
go:
96+
package: postgres
97+
out: postgres
98+
sql_package: pgx/v5
99+
overrides:
100+
- column: users.id
101+
go_type:
102+
import: github.com/yourorg/yourproject/internal/domain
103+
type: "UserID"
104+
```
105+
106+
With this configuration, sqlc will generate Go code that uses your TypeID type directly:
107+
108+
```go
109+
package domain
110+
111+
import "github.com/sumup/typeid"
112+
113+
type UserPrefix struct{}
114+
115+
func (UserPrefix) Prefix() string {
116+
return "user"
117+
}
118+
119+
type UserID = typeid.Sortable[UserPrefix]
120+
121+
type User struct {
122+
ID UserID
123+
Name string
124+
// ... other fields
125+
}
126+
```
127+
128+
You can then use your TypeID types directly in your queries:
129+
130+
```sql
131+
-- name: CreateUser :one
132+
INSERT INTO users (
133+
id,
134+
name
135+
) VALUES (
136+
@id,
137+
@name
138+
) RETURNING *;
139+
140+
-- name: GetUser :one
141+
SELECT * FROM users
142+
WHERE id = @id;
143+
```
144+
145+
And call them from Go:
146+
147+
```go
148+
userID := typeid.Must(typeid.New[domain.UserID]())
149+
user, err := queries.CreateUser(ctx, postgres.CreateUserParams{
150+
ID: userID,
151+
Name: "Karl",
152+
})
153+
```
154+
155+
## Using with oapi-codegen
156+
157+
TypeIDs can be used with [oapi-codegen](https://github.com/oapi-codegen/oapi-codegen) to generate type-safe API clients and servers. Use the `x-go-type` and `x-go-type-import` extensions in your OpenAPI specification:
158+
159+
```yaml
160+
paths:
161+
/users/{user_id}:
162+
parameters:
163+
- in: path
164+
name: user_id
165+
description: The ID of the uesr to retrieve.
166+
required: true
167+
schema:
168+
type: string
169+
example: user_01hf98sp99fs2b4qf2jm11hse4
170+
x-go-type: "domain.UserID"
171+
x-go-type-import:
172+
path: github.com/yourorg/yourproject/internal/domain
173+
174+
components:
175+
schemas:
176+
User:
177+
type: object
178+
properties:
179+
id:
180+
type: string
181+
description: Unique identifier of the user.
182+
example: user_01hf98sp99fs2b4qf2jm11hse4
183+
x-go-type: "domain.UserID"
184+
x-go-type-import:
185+
path: github.com/yourorg/yourproject/internal/domain
186+
name:
187+
type: string
188+
```
189+
190+
The generated code will use your TypeID types:
191+
192+
```go
193+
type User struct {
194+
Id domain.UserID `json:"id"`
195+
Name string `json:"name"`
196+
}
197+
```
198+
199+
TypeIDs implement `encoding.TextMarshaler` and `encoding.TextUnmarshaler`, so they work with JSON encoding/decoding in generated API code without any additional configuration.
200+
59201
### Maintainers
60202

61203
- [Johannes Gräger](mailto:johannes.graeger@sumup.com)

0 commit comments

Comments
 (0)