Tutorial part-3: key-value store - increment and decrement operations
Tags: serverless, javascript, database, tutorial
Published: 2022-12-27 11:05:38

Hi and welcome to part-3 of the [key-value database](https://dev.to/restdbjones/part-1-key-value-store-bji) tutorial for [codehooks.io](https://codehooks.io) serverless JavaScript. In this part we'll focus on how to increment and decrement values in the built-in key-value database.

Increment and decrement operations are commonly supported in [key-value databases](https://en.wikipedia.org/wiki/Key%E2%80%93value_database), and they can be useful for a variety of applications.

One benefit of increment and decrement operations is that they allow you to update a value in the database without having to read the current value, update it, and then write the updated value back to the database. This can be more efficient than performing these steps separately, especially if the value is being updated frequently.

Increment and decrement operations can also be useful for maintaining counters or other types of numerical data in the database. For example, you could use an increment operation to count the number of times a user has visited a webpage, or you could use a decrement operation to reduce a stock quantity in an online store when an item is purchased.

Overall, increment and decrement operations can provide a simple and efficient way to update numerical values in a key-value database.

## Key-value store API for incrementing and decrementing values
The initial value of an incremented or decremented key-value is always 0. You can increment or decrement a value with any positive `integer`. The minimal code example below shows usage of the two functions `incr` and `decr` with the Datastore API.

```js
// connect to key-value store
const db = await Datastore.open();

// increment value
const val1 = await db.incr('myValue', 1);
// decrement value
const val2 = await db.decr('myValue', 1);
console.log("key-val", val1, val2);
```

Lets continue with some more realistic and practical code examples.

## Code example: Count user API traffic

The code example below shows a simple REST API endpoint that increments a counter in the key-value store each time it's called from a client app.

```js
import app from 'codehooks-js' // Standard JS lib for express style code

// Create a GET endpoint route
app.get('/myendpoint/:userID', myFunc);

// serverless function
async function myFunc(req, res) {
  // get userID from the URL, e.g. /myendpoint/9x00fbb
  const {userID} = req.params;
  // connect to key-value store
  const db = await Datastore.open();

  // increment api count by userID
  const count = await db.incr(`API-count-${userID}`, 1);
  res.json({count}); // returns {"count": 1}, {"count": 2}, etc.
}

export default app.init(); // Bind functions to the serverless cloud
```

Some example values in the key-value store, after some usage of the endpoint, might look like the key-values shown below:

```js
{ key: 'API-count-9x00fbb', value: 4 }
{ key: 'API-count-9x00fea', value: 1 }
{ key: 'API-count-out32xz', value: 5 }
{ key: 'API-count-qar870f', value: 3 }
```

## Code example: reduce a stock quantity in an e-commerce online store

Lets say you fill and re-stock your warehouse by calling the key-value store API.

E.g. `db.set('in-stock-TeslaModelZ', 100)`, `db.set('in-stock-TeslaModelX', 45)`

Having an `in-stock` count of our products will enable us to create an endpoint for purchasing and reducing the in-stock count like shown in  the code example below.

```js
import app from 'codehooks-js' // Standard JS lib for express style code

app.post('/checkout/:basketID', async (req, res) => {
  // get basketID from the URL, e.g. /checkout/xyz123
  const {basketID} = req.params;
  const {quantity, product} = req.body;
  // connect to key-value store
  const db = await Datastore.open();

  // decrement value
  const stock = await db.decr(`in-stock-${product}`, quantity);
  res.json({stock, product});
})

export default app.init(); // Bind functions to the serverless cloud
```

The code example below shows how a JavaScript client can `POST` a purchase and a quantity by calling this REST API endpoint:

```js
const MY_API_KEY = 'XXXXX'; // use JWT and JWKS for secure API endpoint
const MY_BASKET_ID = 'xyz123'; // example id

let headersList = {
 "Accept": "*/*",
 "x-api-key": MY_API_KEY,
 "Content-Type": "application/json"
}

let bodyContent = JSON.stringify({
  "product": "TeslaModelZ",
  "quantity": 1
});

let response = await fetch("https://keyvaldemo-f0fe.api.codehooks.io/prod/checkout/" + MY_BASKET_ID, { 
  method: "POST",
  body: bodyContent,
  headers: headersList
});

let data = await response.json();
console.log(data);
```

Example response:

```js
{
  "stock": 97,
  "product": "TeslaModelZ"
}
````

This part-3 of the key-value store tutorial has shown how you can use the increment and decrement operations in serverless JavaScript functions with [codehooks.io](https://codehooks.io).

The next [Part-4: Working with multiple values and streams](https://codehooks.io/docs/tutorials/key-val-store/part-4-working-with-multiple-values-and-streams).