Skip to main content

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.

warning

getArray is deprecated. It remains available for compatibility, but new integrations should use listArrayItems and opaque cursor pagination. No removal date is currently scheduled.

warning

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.

warning

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

DeprecatedReplacementPrimary change
getArraylistArrayItemsOffset pagination to cursor pagination
setArrayItemupsertArrayItemOptional service-generated ID to required customer-owned itemId
setArrayreplaceArrayItemsUnidentified replacement values to explicit item identities

Common workflow replacements:

Earlier workflowReplacement
Read an entire array and scan it client-sidelookupArrayItems
Issue several single-item deletesdeleteArrayItems

Before you migrate

  • Define a stable domain itemId for 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[].extensions rather than message text.

Migrate getArray to listArrayItems

Behavior differences

getArraylistArrayItems
skip and takeafter and first
Offset paginationForward cursor pagination
take: 0 means unlimitedfirst is 1–500
DeprecatedRecommended

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

  • values becomes items.
  • 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 itemId fields.

Mixed-client rollout considerations

  • Legacy setArrayItem updates preserve an existing stored itemId.
  • Legacy inserts do not store itemId and can introduce fallback items or duplicates.
  • Legacy setArray replacement discards stored itemId fields.
  • Retain compatible value.id values while old clients still depend on them.
  • Migrate whole-array writers before relying on explicit itemId values that are absent from value.id.

Migration checklist

  1. Inventory callers of the three deprecated operations.
  2. Define a stable domain itemId for each item.
  3. Migrate whole-array setArray writers.
  4. Migrate item writes to upsertArrayItem.
  5. Replace offset pagination with cursor traversal.
  6. Replace client-side scans with lookupArrayItems.
  7. Replace repeated item deletions with deleteArrayItems.
  8. Update clients to consume page information, counts, and returned item data.
  9. Remove assumptions about selector-aligned response order.
  10. Monitor lookup results and deletedCount for 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.

Was this page helpful?