# Batch requests

Source: https://developers.swell.is/backend-api/batch-requests

Send many operations in a single request with the `/:batch` endpoint. Operations run in parallel and independently of each other, which makes a batch a way to save round trips rather than a way to group changes: if one fails, the others still apply. When you need all-or-nothing behavior, use a [transaction](https://developers.swell.is/backend-api/transactions) instead.

### Making a request

Post an array of operations. Each one takes a `url`, an optional `method`, and optional `data`. An operation that doesn't name a method inherits the method of the batch request itself, so a batch sent with `post` runs its children as `post` unless they say otherwise.

**Batch several operations**

**Node**

```javascript
await swell.post('/:batch', [
  {
    url: '/products',
    data: { name: 'Longsword', price: 50 },
  },
  {
    url: '/products/5c8fb5e1ed2faf8c79da492a',
    method: 'put',
    data: { price: 29.99 },
  },
  {
    url: '/categories/5ca9871f9b14d199072432a1',
    method: 'get',
  },
]);
```

### Response

The response mirrors the shape you sent. An array of operations returns an array of results in the same order, and each entry is what that operation would have returned on its own.

**Batch response**

**Node**

```json
[
  {
    "id": "5cad15bc9b14d1990724663a",
    "name": "Longsword",
    "price": 50
  },
  {
    "id": "5c8fb5e1ed2faf8c79da492a",
    "price": 29.99
  },
  {
    "id": "5ca9871f9b14d199072432a1",
    "name": "Widgets"
  }
]
```

### Naming operations

Send an object instead of an array to name each operation. The response comes back keyed by the same names, which saves you matching results by position. In this form you can also set `$locale` and `$currency` once at the top level, and every operation that doesn't set its own inherits them.

**Named operations**

**Node** `Request`

```javascript
await swell.get('/:batch', {
  $currency: 'EUR',
  products: {
    url: '/products',
    data: { limit: 10 },
  },
  categories: {
    url: '/categories',
    data: { limit: 5 },
  },
});
```

**Node** `Response`

```json
{
  "products": {
    "count": 112,
    "results": []
  },
  "categories": {
    "count": 8,
    "results": []
  }
}
```

### Scoping to one collection

Put a collection in the batch URL and each operation's `url` is resolved relative to it. An operation with no `url` targets the collection itself.

**Scope a batch to a collection**

**Node**

```javascript
// Both operations resolve under /products
await swell.post('/:batch/products', [
  {
    data: { name: 'Longsword', price: 50 },
  },
  {
    url: '5c8fb5e1ed2faf8c79da492a',
    method: 'put',
    data: { price: 29.99 },
  },
]);
```

### Errors

A failed operation doesn't stop the rest of the batch. Its place in the response carries an `$error` instead of a result, and every other operation still runs and still applies. Check each entry before treating the batch as a whole as successful.

**A failed operation**

**Node**

```json
[
  {
    "id": "5cad15bc9b14d1990724663a",
    "name": "Longsword",
    "price": 50
  },
  {
    "$error": "Resource not found /products/does-not-exist"
  }
]
```

### Limits

- A batch can carry up to 1,000 operations. Beyond that the request is rejected before anything runs.
- Operations run 10 at a time, so a large batch still completes in order of magnitude fewer round trips without flooding the database.
- A batch counts against your [rate limit](https://developers.swell.is/backend-api/rate-limits) as the sum of its operations, not as one request.
