Skip to content

Put (Create/Replace)

The Put API is how you change the data in your Store. It handles both creating new Items and updating existing Items, with the simple behavior of replacing anything at the same key path. For these examples we’ll use the schema defined in Example: Movies Schema.

Creating New Items

The Put API adds new Items to your Store. You can either provide an Item that has all of its ID fields populated, or if you have an initialValue field you can leave it unpopulated to allow StatelyDB to choose the ID. In this example, we add a new Movie, and we don’t populate its id field because that field is defined with an initialValue of uuid, so StatelyDB will assign a new UUID to it.

15 collapsed lines
1
package main
2
3
import (
4
"context"
5
"fmt"
6
"os"
7
"slices"
8
"strconv"
9
"time"
10
11
"github.com/StatelyCloud/go-sdk/stately"
12
// This is the code you generated from schema
13
"github.com/StatelyCloud/stately/go-sdk-sample/schema"
14
)
15
16
func samplePut(
17
ctx context.Context,
18
client stately.Client,
19
) ([]byte, error) {
20
movie := &schema.Movie{
21
// Id: []byte(...) will be auto-generated by put
22
// because of its uuid initialValue
23
Title: "Starship Troopers 2",
24
Genre: "Sci-Fi",
25
Year: 1997,
26
Duration: int64(
27
(2*time.Hour + 9*time.Minute).Seconds(),
28
),
29
Rating: "R",
30
}
31
32
item, err := client.Put(ctx, movie)
33
if err != nil {
34
return nil, err
35
}
36
37
movie = item.(*schema.Movie)
38
return movie.Id, nil
39
}

Replacing Items

Put can also be used to replace existing Items. We say “replace” instead of “update” because the new Item completely replaces the old Item. To replace an existing Item, you Put an Item that has the same ID fields as an existing Item, and that will overwrite the original Item.

15 collapsed lines
1
package main
2
3
import (
4
"context"
5
"fmt"
6
"os"
7
"slices"
8
"strconv"
9
"time"
10
11
"github.com/StatelyCloud/go-sdk/stately"
12
// This is the code you generated from schema
13
"github.com/StatelyCloud/stately/go-sdk-sample/schema"
14
)
15
16
func sampleUpdate(
17
ctx context.Context,
18
client stately.Client,
19
movieID []byte,
20
) error {
21
// Replace the Movie at movieID with this new item.
22
_, err := client.Put(ctx, &schema.Movie{
23
Id: movieID,
24
Title: "Starship Troopers",
25
Year: 1997,
26
Genre: "Sci-Fi",
27
Duration: int64(
28
(2*time.Hour + 9*time.Minute).Seconds(),
29
),
30
Rating: "R",
31
})
32
if err != nil {
33
return err
34
}
35
return nil
36
}

Batch Put

If you have multiple Items, it can be more efficient to put them all at once using PutBatch. This allows up to 50 Items, and the puts are applied atomically, meaning either all puts will succeed, or none of them will. You can combine new Items and updates to existing Items in the same batch - Items that have an initialValue will always be newly created, while existing Items will be replaced.

15 collapsed lines
1
package main
2
3
import (
4
"context"
5
"fmt"
6
"os"
7
"slices"
8
"strconv"
9
"time"
10
11
"github.com/StatelyCloud/go-sdk/stately"
12
// This is the code you generated from schema
13
"github.com/StatelyCloud/stately/go-sdk-sample/schema"
14
)
15
16
func sampleBatchPut(
17
ctx context.Context,
18
client stately.Client,
19
) error {
20
// Put some thriller movies
21
_, err := client.PutBatch(ctx,
22
&schema.Movie{
23
Title: "Seven",
24
Rating: "R",
25
Year: 1995,
26
Genre: "Thriller",
27
Duration: int64(
28
(2*time.Hour + 7*time.Minute).Seconds(),
29
),
30
},
31
&schema.Movie{
32
Title: "Heat",
33
Rating: "R",
34
Year: 1995,
35
Genre: "Thriller",
36
Duration: int64(
37
(2*time.Hour + 50*time.Minute).Seconds(),
38
),
39
},
40
)
41
return err
42
}

Unique Constraints

When StatelyDB chooses the ID for your initialValue field, the Item is guaranteed to be new - it won’t overwrite any existing Item. You can use this to your advantage to implement “unique constraints”—if a value is generated for an initialValue field and that field is used in one of the Item’s key paths, StatelyDB also ensures that an Item doesn’t already exist under any of the Item’s other key paths. For example, imagine you have a User Item type that defines two key paths, /user-:id and /email-:email, and the id field has initialValue: "uuid". When you Put a User without specifying its ID, StatelyDB will generate a new UUID for the ID, and will fail the Put if another User already exists with the same email.

Partial and Conditional Updates

StatelyDB does not currently have an API for partial updates (changing only some fields of an Item), nor does it have a way to specify constraints on updates. For now, those operations are best handled using a transaction. Within a transaction, you can Get the existing state of an Item, make changes to it (or return early if your condition is not met), and then Put the Item back to the Store. The transaction guarantees that the Item didn’t change during that sequence of operations. This is very flexible since you can implement any logic you want within a transaction, but we do intend to introduce convenience APIs for partial updates and some common conditions in the future.