edgedb / edgedb-go

The official Go client library for EdgeDB
https://pkg.go.dev/github.com/edgedb/edgedb-go
Apache License 2.0
168 stars 11 forks source link

Edgedb `json` value be mapped to `json.RawMessage` go types instead of `[]byte`. #315

Open chirino opened 3 months ago

fmoor commented 3 months ago

Thanks for opening the issue! I'm not sure I understand what this is asking for though. json.RawMessage is a []byte type and can be used in place of []byte with the EdgeDB client.

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"

    "github.com/edgedb/edgedb-go"
)

func main() {
    ctx := context.Background()
    client, err := edgedb.CreateClient(ctx, edgedb.Options{})
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    var result struct {
        Thing json.RawMessage `edgedb:"thing"`
    }
    err = client.QuerySingle(ctx, `SELECT { thing := to_json('{"hello": "world"}') }`, &result)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(string(result.Thing))
}

Maybe there are some scenarios where this doesn't work? Let us know. Thanks!

chirino commented 3 months ago

if you put that query into an example.edgeql the generator produces these types:

type ExampleResult struct {
    Thing []byte `edgedb:"thing"`
}

It would be better if it generated:

type ExampleResult struct {
    Thing json.RawMessage `edgedb:"thing"`
}

json marshaling a json.RawMessage does the thing you would expect. json Marshaling []byte, marshals as list of numbers.

and if thing was optional, it uses edgedb.OptionalBytes. That json marshals to some weird encoded string.

fmoor commented 3 months ago

Ok I see. That makes sense.

It turns out that we can decode to json.RawMessage but we currently don't support encoding to it. Before potentially changing the generator I think we should support both operations. I'll try to work out a good way of doing this.

If it happens that the only thing you want to do with your query results is json encode them, then you can use the JSON variant of the generated function. This also has a performance improvement because the query result comes from the server as json bytes and doesn't need to be marshaled again. I understand though that there are many times that json encoding is often only one of the things that a query result is used for.