Upsert either updates an existing record, or inserts a new one. It's the more flexible strategy, but dealing with it is a bit more complex.
To update an object, the Unit21 API supports two different methods:
- a) a PUT request to an
/update
endpoint, using the object'sunit21_id
- b) a POST request to a
/create
endpoint, using the object'sexternal_id
The PUT option is the traditional RESTful method for handling updates.
The POST option lets you create and update objects through the same /create
endpoint.
This option is called an upsert.
Upsert = Update + insert
For any endpoint that supports upsert, you MAY update all objects through POST requests to /create
.
In these cases, the /update
endpoint is not strictly necessary.
For its flexibility and convenience, developers typically prefer to create and update objects through the single /create
endpoint. However, using upserts makes queries more complex. For its simplicity, you might prefer to update with the PUT request in some cases.
Upsert creates and updates through POST requests to /create
/create
The word "upsert" is a combination of the words "update" and "insert". When the Unit21 API receives a valid POST request to an endpoint that supports upserts, for each request's fields:
- empty fields will have a new value inserted
- non-empty fields will be updated
For example, you could create an event with a POST to /events/create
, with the following request body:
{
"general_data": {
"event_id": "event1000",
"event_type": "transaction",
"event_time": 1623145011
},
"transaction_data": {
"sender_instrument_id": "instrument-100",
"amount": 15000
}
}
This creates a new event, event1000
:
{"event_id":"event1000","previously_existed":false,"unit21_id":"4969806"}
Now, if you want to update or add values, you could use the event_id
to upsert with another POST to /events/create
. The following request body does two things:
- Updates the
transaction_data.amount
field - Inserts a new value to
general_data.tags
:
{
"general_data": {
"tags": [
"suspicious:new_account"
],
"event_id": "event1000",
"event_type": "transaction",
"event_time": 1623145011
},
"transaction_data": {
"sender_instrument_id": "instrument-100",
"amount": 25000
}}
For single fields, like amount
, the upserts simply overwrite the field with new posted values. For array fields, how the data merge depends on the options you pass. Data merging on updates covers these options detail.
Upsert benefits: one endpoint and batch updates
As you can create and update through one endpoint, upserts are convenient. Additionally, when you upsert, you do not need to wait for Unit21 to accept the entity in the system, as you do with a PUT.
Secondly, as the /create
endpoints support batch uploads, you can also use upserts to update a large number of objects at the same time
Block upserts with the option upsert_on_conflict
upsert_on_conflict
To prevent POST requests from overwriting existing data, set the value for options.upsert_on_conflict
to false
. This strategy blocks upserts for individual objects and for batches.
Update provides simpler queries
The convenience of upserts comes with two tradeoffs:
- To update a single field, an upsert MUST include all fields required by the endpoint
- Upsert does not follow the standard syntax of REST APIs.
Some developers prefer to use the PUT method to update some or all Unit21 objects. Besides offering a method that's well-known to all developers familiar with REST, it also allows for simpler queries. For example, to update the event100
object created in the preceding section, a developer could also send a PUT to /events/{unit21_id}/update
. The request body is noticeably shorter:
{
"general_data": {
"tags": [
"suspicious:new_account"
],
"transaction_data": {
"amount": 25000
}
}
As with upserts, you can pass options to configure how updates merge array data. Data merging on updates covers these options' details.