Migrate from deprecated Array APIs
Deprecation status
getArray, setArrayItem, and setArray are deprecated. They remain available for backward compatibility, and no removal date is currently scheduled. Any future removal requires a separately announced breaking change.
getArray is deprecated. It remains available for compatibility, but new integrations should use listArrayItems and opaque cursor pagination. No removal date is currently scheduled.
setArrayItem is deprecated. It remains available for compatibility, but new integrations should use upsertArrayItem with a customer-owned itemId. No removal date is currently scheduled.
setArray is deprecated. It remains available for compatibility, but new integrations should use replaceArrayItems with explicit itemId values. No removal date is currently scheduled.
New integrations should use the replacements below.
Replacement summary
| Deprecated | Replacement | Primary change |
|---|---|---|
getArray | listArrayItems | Offset pagination to cursor pagination |
setArrayItem | upsertArrayItem | Optional service-generated ID to required customer-owned itemId |
setArray | replaceArrayItems | Unidentified replacement values to explicit item identities |
Common workflow replacements:
| Earlier workflow | Replacement |
|---|---|
| Read an entire array and scan it client-side | lookupArrayItems |
| Issue several single-item deletes | deleteArrayItems |
Before you migrate
- Define a stable domain
itemIdfor each item. - Decide whether old clients depend on
value.id. - Inventory all writers, including whole-array writers.
- Do not assume response order matches request order.
- Update clients to inspect
errors[].extensionsrather than message text.
Migrate getArray to listArrayItems
Behavior differences
getArray | listArrayItems |
|---|---|
skip and take | after and first |
| Offset pagination | Forward cursor pagination |
take: 0 means unlimited | first is 1–500 |
| Deprecated | Recommended |
Before: Offset pagination
query GetFavorites($input: GetArrayInput!) {
getArray(input: $input) {
data { id value }
totalCount
}
}
{
"input": {
"scope": "USER",
"key": "content:favorites",
"skip": 20,
"take": 20
}
}
```json
{
"data": {
"getArray": {
"data": [
{
"id": "66b100000000000000000001",
"value": {
"title": "Example Movie",
"mediaType": "MOVIE"
}
}
],
"totalCount": 2
}
}
}
The offset selects a page relative to the current array contents.
After: Cursor pagination
query ListFavorites($input: ListArrayItemsInput!) {
listArrayItems(input: $input) {
data { id itemId value }
totalCount
pageInfo { hasNextPage endCursor }
}
}
{
"input": {
"scope": "USER",
"key": "content:favorites",
"first": 20,
"after": "<opaque cursor returned by the service>"
}
}
{
"data": {
"listArrayItems": {
"data": [
{
"id": "66b100000000000000000001",
"itemId": "movie:100",
"value": {
"title": "Example Movie",
"mediaType": "MOVIE"
}
}
],
"totalCount": 2,
"pageInfo": {
"hasNextPage": true,
"endCursor": "<opaque cursor returned by the service>"
}
}
}
}
Store the returned cursor only as an opaque continuation token. Do not decode or construct it.
Migrate setArrayItem to upsertArrayItem
Behavior differences
setArrayItem optionally accepts a service-generated id. upsertArrayItem requires a customer-owned itemId and can insert or update without a previous read. value.id does not need to equal itemId.
Before: Service-generated ID
mutation SetFavorite($input: SetArrayItemInput!) {
setArrayItem(input: $input) {
acknowledged
item { id value }
}
}
{
"input": {
"scope": "USER",
"key": "content:favorites",
"id": "66b100000000000000000001",
"value": {
"title": "Example Movie",
"mediaType": "MOVIE"
}
}
}
{
"data": {
"setArrayItem": {
"acknowledged": true,
"item": {
"id": "66b100000000000000000001",
"value": {
"title": "Example Movie",
"mediaType": "MOVIE"
}
}
}
}
}
After: Customer-owned itemId
mutation UpsertFavorite($input: UpsertArrayItemInput!) {
upsertArrayItem(input: $input) {
acknowledged
insertedCount
matchedCount
modifiedCount
deletedCount
item { id itemId value }
}
}
{
"input": {
"scope": "USER",
"key": "content:favorites",
"itemId": "movie:100",
"value": {
"title": "Example Movie",
"mediaType": "MOVIE"
}
}
}
{
"data": {
"upsertArrayItem": {
"acknowledged": true,
"insertedCount": 0,
"matchedCount": 1,
"modifiedCount": 1,
"deletedCount": 0,
"item": {
"id": "66b100000000000000000001",
"itemId": "movie:100",
"value": {
"title": "Example Movie",
"mediaType": "MOVIE"
}
}
}
}
}
The customer-owned itemId remains stable even when the service-generated ID is retained internally.
Migrate setArray to replaceArrayItems
Behavior differences
valuesbecomesitems.- Every item has a required, unique
itemId. - Empty replacement arrays remain invalid.
- Omitted old items are removed.
- Replacement recreates items, so service-generated IDs change.
- Returned items preserve input order.
Before: Unidentified replacement items
mutation ReplaceFavorites($input: SetArrayInput!) {
setArray(input: $input) {
acknowledged
data { id value }
}
}
{
"input": {
"scope": "USER",
"key": "content:favorites",
"values": [
{
"title": "Example Movie",
"mediaType": "MOVIE"
},
{
"title": "Another Movie",
"mediaType": "MOVIE"
}
]
}
}
{
"data": {
"setArray": {
"acknowledged": true,
"data": [
{
"id": "66b100000000000000000001",
"value": {
"title": "Example Movie",
"mediaType": "MOVIE"
}
}
]
}
}
}
After: Explicit itemId values
mutation ReplaceFavorites($input: ReplaceArrayItemsInput!) {
replaceArrayItems(input: $input) {
acknowledged
items { id itemId value }
}
}
{
"input": {
"scope": "USER",
"key": "content:favorites",
"items": [
{
"itemId": "movie:100",
"value": {
"title": "Example Movie",
"mediaType": "MOVIE"
}
},
{
"itemId": "movie:200",
"value": {
"title": "Another Movie",
"mediaType": "MOVIE"
}
}
]
}
}
{
"data": {
"replaceArrayItems": {
"acknowledged": true,
"items": [
{
"id": "66b100000000000000000001",
"itemId": "movie:100",
"value": {
"title": "Example Movie",
"mediaType": "MOVIE"
}
},
{
"id": "66b100000000000000000002",
"itemId": "movie:200",
"value": {
"title": "Another Movie",
"mediaType": "MOVIE"
}
}
]
}
}
}
Replace client-side scanning with lookupArrayItems
Pass known itemIds, service-generated ids, or both to lookupArrayItems. Unknown selectors are omitted and results follow requested sorting rather than selector order.
Replace repeated deletions with deleteArrayItems
Pass the union of itemIds and ids to one deleteArrayItems mutation. All qualifying legacy duplicates are deleted, and deletedCount reports the number of documents removed.
Existing-data compatibility
Qualifying legacy identities
When stored itemId is absent, a legacy item can derive identity from its own value.id when it is a valid identifier string or a canonical, non-negative safe integer representation addressable by the corresponding string itemId.
A stored string itemId is authoritative and takes precedence over value.id.
Reads do not backfill data
listArrayItems and lookupArrayItems do not write, backfill, or update timestamps.
Lazy migration during upsert
Upserting a qualifying legacy identity writes the explicit itemId, retains the service-generated ID of the surviving item, and removes matching duplicates. No separate backfill operation is required.
Legacy duplicates
- Lookup returns matching duplicates as separate rows.
- Batch delete removes every matching duplicate.
- Upsert retains one survivor and removes the others.
- Legacy whole-array replacement can discard stored
itemIdfields.
Mixed-client rollout considerations
- Legacy
setArrayItemupdates preserve an existing storeditemId. - Legacy inserts do not store
itemIdand can introduce fallback items or duplicates. - Legacy
setArrayreplacement discards storeditemIdfields. - Retain compatible
value.idvalues while old clients still depend on them. - Migrate whole-array writers before relying on explicit
itemIdvalues that are absent fromvalue.id.
Migration checklist
- Inventory callers of the three deprecated operations.
- Define a stable domain
itemIdfor each item. - Migrate whole-array
setArraywriters. - Migrate item writes to
upsertArrayItem. - Replace offset pagination with cursor traversal.
- Replace client-side scans with
lookupArrayItems. - Replace repeated item deletions with
deleteArrayItems. - Update clients to consume page information, counts, and returned item data.
- Remove assumptions about selector-aligned response order.
- Monitor lookup results and
deletedCountfor legacy duplicates.
Deprecated API compatibility reference
For migration-only compatibility, getArray defaults skip to 0, take to 20, sort to id, and sortDirection to asc. take: 0 requests an unlimited result set. These semantics do not apply to listArrayItems.