# Included Resources

APIs frequently support returning multiple resource types in a single request. For instance, an endpoint may allow you to fetch an author as well as that author's books. In this example, `authors` and `books` are two different resource types.

This plugin is designed to allow you to dispatch a single action that includes multiple types. It is optimized to receive normalized data, such as what is returned from [`normalizr`](https://github.com/paularmstrong/normalizr).

## Usage

Add this plugin when you call [`resourceReducer`](https://redux-resource.js.org/api-reference/resource-reducer). Be sure to add it to the "primary" resource slice, as well as to the included resource slices.

```javascript
import { resourceReducer } from 'redux-resource';
import { includedResources } from 'redux-resource-plugins';

const authorReducer = resourceReducer('authors', {
  plugins: [includedResources]
});

const booksReducer = resourceReducer('books', {
  plugins: [includedResources]
});
```

This plugin doesn't come with any custom action types. Instead, it changes the way the state is transformed with the built-in successful create, update or read CRUD [action type](https://redux-resource.js.org/api-reference/action-types): `CREATE_RESOURCES_SUCCEEDED`, `UPDATE_RESOURCES_SUCCEEDED` and `READ_RESOURCES_SUCCEEDED`.

When your actions have an `includedResources` object, they will be added to the appropriate slices.

An example of using `includedResources` is the following:

```javascript
import { actionTypes } from 'redux-resource';
import store from './store';

store.dispatch({
  type: actionTypes.READ_RESOURCES_SUCCEEDED,
  resourceType: 'authors',
  resources: [{
    id: 10,
    name: 'Sarah'
  }],
  includedResources: {
    // Resources are key'd off by their name.
    // The value can be an Object or an Array.

    // Here we pass books as an Object. `normalizr` returns
    // a shape like this.
    books: {
      23: {
        id: 23,
        name: 'Some book'
      },
      100: {
        id: 50,
        name: 'Another book'
      }
    },

    // Notice here that comments is an Array. This format works, too.
    comments: [
      {
        id: 23,
        name: 'Great author!'
      },
      {
        id: 100,
        name: 'One of my favorite authors'
      }
    ]
  }
});
```

Be sure to use `includedResources` on *every* resource slice that can appear in `includedResources`. In the above example, we would want to include the plugin for our `authors`, `books`, and `comments`.

This plugin will respect the `mergeResources` and `mergeMeta` action properties.

## Related Reading

Not every API returns included resources in a normalized manner, so a different plugin may be more appropriate for certain backends. As an example, JSON API does not provide included resources in a format that can be interpreted by this plugin.

For more on this subject, refer to the [Related Resources recipe](https://redux-resource.js.org/recipes/related-resources).
