# Unique Identifiers

When you create an item for an [entity](https://docs.vendia.com/platform/vendia-terminology#entity) in your project, Vendia generates a unique `id` for the item. You can use this `id` to perform CRUD operations on the item.

_Unique Identifiers_ allow you to perform the same CRUD operations using a custom, user defined identifier instead of the Vendia generated `id`.

When using unique identifiers, Vendia will still generate a unique `id` per item. Both the Vendia generated `id` and your _Unique Identifiers_ can be used interchangeably to identify items.

## Adding Unique Identifiers

Specific fields in the JSON schema can be marked as unique identifiers using the `x-vendia-unique` definition.

Once marked, Vendia will generate new queries and mutations in your [GraphQL schema](https://docs.vendia.com/platform/operational/scalar-data/graphql) for any [entity](https://docs.vendia.com/platform/vendia-terminology#entity) with unique identifiers set. The new queries and mutations will allow you to specify either `id` or any of the specified _unique identifiers_ when referencing items for CRUD operations.

Here is an example of an `x-vendia-unique` definition specifying two fields as unique identifiers:

```
"x-vendia-unique": [

"name",

"sku"

],
```

You can also see a full example [in the sample schema section below](https://docs.vendia.com/platform/operational/modeling/unique-identifiers/#sample-schema)

Please also see [limitations](https://docs.vendia.com/platform/operational/modeling/unique-identifiers/#unique-identifier-limits) around unique identifiers.

## Using Unique Identifiers

### Mutations

#### Add Mutations

When creating an item with an add mutation, any unique identifiers specified in the input will also be added to the system.

For example, the following `add_Inventory` mutation will create a new item (that will generate a new `id`) and it will create a new unique identifier for both `name` and `sku`, assuming they do not already exist in the datastore.

```
add_Inventory(

input: {

name: "running shoe",

availableInventory: 945,

warehouse: "US-W-31-A",

sku: "SHO-12-RUN-US"

}
) { transaction { transactionId } }
```

#### Put and Upsert Mutations

Put mutations will perform an [upsert](https://docs.vendia.com/platform/vendia-terminology#upsert) if no identifiers are specified outside of the input, or a normal put operation if an identifier is used.

##### Put

Put operations update an item by replacing the entire item with the input specified in the mutation, if an identifier is specified outside of the input.

For example, the following `put_Inventory` mutation will replace the entire item, specified by the `sku` identifier passed outside of the input.

```
put_Inventory(

sku: "LIM-10-RUN-US"

input: {

name: "running shoe",

availableInventory: 645,

warehouse: "US-W-31-A",

sku: "LIM-10-RUN-US"

}
) { transaction { transactionId } }
```

##### Upsert

[Upsert](https://docs.vendia.com/platform/vendia-terminology#upsert) operations are performed when an identifier is not passed outside of the input. This will either update the item by replacing the entire item with the input specified in the mutation (if the unique identifier exists) or create a new item with the input (if the unique identifier does not exist).

In this example, the following `put_Inventory` mutation will perform an [upsert](https://docs.vendia.com/platform/vendia-terminology#upsert) and will either create a new item if there is no Inventory product with the `sku``LIM-10-RUN-US` or will replace the existing item.

```
put_Inventory(

input: {

availableInventory: 12,

warehouse: "EU-W-12-C",

sku: "LIM-10-RUN-US"

}
) { transaction { transactionId } }
```

#### Update / Remove / Erase Mutations

With unique identifiers specified on the entity, these mutations will allow you to reference specific items by their unique identifier.

For example, you can use the following `update_Inventory` mutation to update the `availableInventory` field, by using the unique identifier `sku` to identify the Inventory

```
update_Inventory(

sku: "LIM-10-RUN-US"

input: {

availableInventory: 5

}
) {

result {

_id

name

color

}
 }
```

### Queries

Both Get and List Version queries can also use unique identifiers to specify the item.

Example Get query:

```
query getInventoryQuery {

get_Inventory(name: "running shoe") {

sku

name

warehouse

availableInventory

}
}
```

Example List Version query:

```
query listInventoryVersionsQuery {

list_InventoryVersions(sku: "LIM-10-RUN-US") {

versions {

block

ordinal

}
  }
}
```

## Unique Identifier Limits

- Limited to 2 unique identifiers per entity
- Unique identifiers can only be set on top-level array data types. See our [data modeling](https://docs.vendia.com/platform/operational/modeling/data-modeling) documentation
- Unique identifiers are limited to number or string values
- You cannot make an existing entity field a unique identifier
- All **workspaces** are required to have read access for unique identifiers

- This means that when specifying `aclInputs`, you must include `*` read access for unique identifiers.
  - As a result, locally [erasing](https://docs.vendia.com/platform/erasure/erasure) unique identifier fields is not supported, but global erasure is supported.
- Unique identifiers cannot be modified once added to an item
- To remove a unique identifier, you must remove the entire item

## Sample Schema

The following sample schema has two unique identifiers on two different entity types.

```
{

"$schema": "http://json-schema.org/draft-07/schema#",

"$id": "http://vendia.net/schemas/demos/track-and-trace.json",

"title": "Track and Trace",

"description": "Track and trace shipments among a manufacturer, shipper, and retailer",

"type": "object",

"properties": {

"Inventory": {

"description": "Inventory information",

"type": "array",

"items": {

"type": "object",

"properties": {

"name": {

"description": "Product name",

"type": "string"

},

"sku": {

"description": "Product SKU",

"type": "string"

},

"warehouse": {

"description": "Manufacturer warehouse code",

"type": "string"

},

"availableInventory": {

"description": "Available inventory",

"type": "integer"

}

},

"x-vendia-unique": ["name", "sku"]

}

},

"Warehouse": {

"description": "Warehouse information",

"type": "array",

"items": {

"type": "object",

"properties": {

"companyName": {

"description": "Company name",

"type": "string"

},

"code": {

"description": "Warehouse code",

"type": "string"

},

"street1": {

"description": "Warehouse Street Address",

"type": "string"

},

"street2": {

"description": "Warehouse Warehouse Street Address Continued",

"type": "string"

},

"city": {

"description": "Warehouse City",

"type": "string"

},

"state": {

"description": "Warehouse State",

"type": "string"

},

"postalCode": {

"description": "Warehouse Postal Code",

"type": "string"

},

"country": {

"description": "Warehouse Country Code",

"type": "string"

},

"phone": {

"description": "Warehouse Phone Number",

"type": "string"

},

"fax": {

"description": "Warehouse Fax Number",

"type": "string"

},

"created": {

"description": "When the Warehouse record was created",

"type": "string",

"format": "date-time"

},

"updated": {

"description": "When Warehouse record was last updated",

"type": "string",

"format": "date-time"

}

},

"x-vendia-unique": ["code", "phone"]

}

}

}

}
```
