# Value types

The Go SDK uses typed wrappers for SurrealDB values like RecordID, UUID, DateTime, and Duration, encoded over CBOR.

The Go SDK communicates with SurrealDB using CBOR (Concise Binary Object Representation) rather than JSON. The SDK provides Go types that map to SurrealDB's data model and handle CBOR serialisation transparently when used in structs or maps.

This page covers the mapping between SurrealDB types and Go types, and how to work with the most common value types.

## API references

<table>
	<thead>
		<tr>
			<th scope="col">Type</th>
			<th scope="col">Description</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td scope="row" data-label="Type"><a href="/docs/reference/golang/api/values/record-id.md"><code>models.RecordID</code></a></td>
			<td scope="row" data-label="Description">A unique record identifier with table name and ID</td>
		</tr>
		<tr>
			<td scope="row" data-label="Type"><a href="/docs/reference/golang/api/values/table.md"><code>models.Table</code></a></td>
			<td scope="row" data-label="Description">A table name</td>
		</tr>
		<tr>
			<td scope="row" data-label="Type"><a href="/docs/reference/golang/api/values/uuid.md"><code>models.UUID</code></a></td>
			<td scope="row" data-label="Description">A UUID v4 or v7 value</td>
		</tr>
		<tr>
			<td scope="row" data-label="Type"><a href="/docs/reference/golang/api/values/datetime.md"><code>models.CustomDateTime</code></a></td>
			<td scope="row" data-label="Description">A datetime value wrapping time.Time</td>
		</tr>
		<tr>
			<td scope="row" data-label="Type"><a href="/docs/reference/golang/api/values/duration.md"><code>models.CustomDuration</code></a></td>
			<td scope="row" data-label="Description">A duration value wrapping time.Duration</td>
		</tr>
		<tr>
			<td scope="row" data-label="Type"><a href="/docs/reference/golang/api/values/geometry.md"><code>models.GeometryPoint</code></a></td>
			<td scope="row" data-label="Description">A geographic point with longitude and latitude</td>
		</tr>
		<tr>
			<td scope="row" data-label="Type"><a href="/docs/reference/golang/api/values/range.md"><code>models.Range</code></a></td>
			<td scope="row" data-label="Description">A range with inclusive or exclusive bounds</td>
		</tr>
	</tbody>
</table>

## Type mapping

The following table shows how SurrealDB types map to Go types when using the SDK.

| SurrealQL type | Go type | CBOR tag |
|---|---|---|
| `null` | `nil` | - |
| `none` | `models.CustomNil` / `models.None` | 6 |
| `bool` | `bool` | - |
| `int` | `int`, `int64`, etc. | - |
| `float` | `float64` | - |
| `decimal` | `models.DecimalString` | 10 |
| `string` | `string` | - |
| `bytes` | `[]byte` | - |
| `datetime` | `models.CustomDateTime` | 12 |
| `duration` | `models.CustomDuration` | 14 |
| `uuid` | `models.UUID` | 37 |
| `record` | `models.RecordID` | 8 |
| `array` | `[]any` or typed slice | - |
| `object` | `map[string]any` or struct | - |
| `geometry<point>` | `models.GeometryPoint` | 88 |
| `geometry<line>` | `models.GeometryLine` | 89 |
| `geometry<polygon>` | `models.GeometryPolygon` | 90 |
| `geometry<multipoint>` | `models.GeometryMultiPoint` | 91 |
| `geometry<multiline>` | `models.GeometryMultiLine` | 92 |
| `geometry<multipolygon>` | `models.GeometryMultiPolygon` | 93 |
| `geometry<collection>` | `models.GeometryCollection` | 94 |

## Working with record IDs

Use [`models.NewRecordID`](/docs/reference/golang/api/values/record-id.md) to construct a `RecordID`, or receive them from query results. The ID can be any CBOR-serializable value (string, integer, array, etc.).

```go
import "github.com/surrealdb/surrealdb.go/pkg/models"

id := models.NewRecordID("persons", "tobie")

numericID := models.NewRecordID("events", 42)
```

To parse a record ID from a string like `"persons:tobie"`, use `ParseRecordID`:

```go
id, err := models.ParseRecordID("persons:tobie")
```

When defining structs for database records, use `*models.RecordID` for the ID field:

```go
type Person struct {
	ID      *models.RecordID `json:"id,omitempty"`
	Name    string           `json:"name"`
	Surname string           `json:"surname"`
}
```

## Working with datetimes

[`CustomDateTime`](/docs/reference/golang/api/values/datetime.md) wraps Go's `time.Time` and handles CBOR encoding with nanosecond precision.

```go
now := models.CustomDateTime{Time: time.Now()}
```

You can use all standard `time.Time` methods directly on a `CustomDateTime` value, since it embeds `time.Time`.

## Working with durations

[`CustomDuration`](/docs/reference/golang/api/values/duration.md) wraps Go's `time.Duration` with SurrealDB-compatible formatting (e.g., `1d2h30m`).

```go
dur := models.CustomDuration{Duration: 2*time.Hour + 30*time.Minute}
fmt.Println(dur.String()) // "2h30m"
```

Use `CustomDurationString` when you need the string representation directly, and call `.ToCustomDuration()` to convert back.

## Working with geometry types

The SDK provides types for all SurrealDB geometry values. [`GeometryPoint`](/docs/reference/golang/api/values/geometry.md) is the most common:

```go
point := models.GeometryPoint{Longitude: -0.118, Latitude: 51.509}
```

Other geometry types compose `GeometryPoint`:

```go
line := models.GeometryLine{
	{Longitude: -0.118, Latitude: 51.509},
	{Longitude: -0.076, Latitude: 51.508},
}

polygon := models.GeometryPolygon{line}
```

## Using None

SurrealDB distinguishes between `null` (SQL NULL) and `none` (absence of a value). Use `models.None` to represent the absence of a value:

```go
surrealdb.Create[any](ctx, db, models.Table("test"), map[string]any{
	"field": models.None,
})
```

## Learn more

- [RecordID reference](/docs/reference/golang/api/values/record-id.md) for detailed constructors and methods
- [UUID reference](/docs/reference/golang/api/values/uuid.md) for UUID types
- [DateTime reference](/docs/reference/golang/api/values/datetime.md) for datetime handling
- [Duration reference](/docs/reference/golang/api/values/duration.md) for duration types and parsing
- [Geometry reference](/docs/reference/golang/api/values/geometry.md) for all geometry types
- [SurrealQL data model](/docs/reference/query-language/language-primitives/data-types.md) for the underlying type system
