I'm using sqlc together with a package that generates an http router based on an OpenAPI spec. I find that I need to do a lot of mapping between sqlc generated types and types for the http responses. This is ok if my queries are relatively simple, but I've found that with joins I end up with a lot of structs that share field types but have dedicated types. If these structs instead had methods whose signatures matched, I could create interfaces that these types implement and use these interfaces in the functions that generate API responses.
For example, say I've got a jobs table and a deliveries table.
CREATE TABLE jobs (
id UUID PRIMARY KEY,
status TEXT NOT NULL,
created TIMESTAMP WITH TIME ZONE NOT NULL,
updated TIMESTAMP WITH TIME ZONE NOT NULL
);
CREATE TABLE deliveries (
id UUID PRIMARY KEY,
job_id UUID UNIQUE NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
status TEXT NOT NULL,
created TIMESTAMP WITH TIME ZONE NOT NULL,
updated TIMESTAMP WITH TIME ZONE NOT NULL
);
And here are two example queries to get a single job and to list all jobs:
-- name: GetJob :one
SELECT jobs.*, deliveries.id AS delivery_id
FROM jobs
LEFT JOIN deliveries ON jobs.id = deliveries.job_id
WHERE jobs.id = $1;
-- name: ListJobs :many
SELECT jobs.*, deliveries.id AS delivery_id
FROM jobs
LEFT JOIN deliveries ON jobs.id = deliveries.job_id;
I end up with two structs whose fields match:
type GetJobRow struct {
ID uuid.UUID `json:"id"`
Status string `json:"status"`
Created time.Time `json:"created"`
Updated time.Time `json:"updated"`
DeliveryID uuid.UUID `json:"delivery_id"`
}
type ListJobsRow struct {
ID uuid.UUID `json:"id"`
Status string `json:"status"`
Created time.Time `json:"created"`
Updated time.Time `json:"updated"`
DeliveryID uuid.UUID `json:"delivery_id"`
}
If these structs had methods for each of the fields, I could create a single JobWithDeliveryID interface and use that in the signature for my function that generates values for my API responses. Without that interface, I need to create two functions that map the types above to the same type for the API response.
Doing this twice is not so bad, but I've found that the types proliferate pretty quickly, while the number of corresponding interfaces I would have to create is relatively low.
I'm using sqlc together with a package that generates an http router based on an OpenAPI spec. I find that I need to do a lot of mapping between sqlc generated types and types for the http responses. This is ok if my queries are relatively simple, but I've found that with joins I end up with a lot of structs that share field types but have dedicated types. If these structs instead had methods whose signatures matched, I could create interfaces that these types implement and use these interfaces in the functions that generate API responses.
For example, say I've got a
jobstable and adeliveriestable.And here are two example queries to get a single job and to list all jobs:
I end up with two structs whose fields match:
If these structs had methods for each of the fields, I could create a single
JobWithDeliveryIDinterface and use that in the signature for my function that generates values for my API responses. Without that interface, I need to create two functions that map the types above to the same type for the API response.Doing this twice is not so bad, but I've found that the types proliferate pretty quickly, while the number of corresponding interfaces I would have to create is relatively low.