--- outline: deep --- # Common API The Feathers database adapters implement a common interface for initialization, pagination, extending and querying. This chapter describes the common adapter initialization and options, how to enable and use pagination, the details on how specific service methods behave and how to extend an adapter with custom functionality.
Every database adapter is an implementation of the [Feathers service interface](../services.md). If there is no adapter available for your database of choice, you can still use it directly in a [custom service](../services.md). We recommend being familiar with Feathers services, service events and hooks and the database before using a database adapter.## Initialization ### `new
Disabling or changing the default pagination is not available in the client. Only `params.query` is passed to the server (also see a [workaround here](https://github.com/feathersjs/feathers/issues/382#issuecomment-288125825))## params.adapter Setting the `adapter` in the [service method `params`](../services.md#params) allows do dynamically modify the database adapter options based on the request. This e.g. allows to temporarily allow multiple entry creation/changes or the pagination settings. ```ts const messages = [ { text: 'message 1' }, { text: 'message 2' } ] // Enable multiple entry insertion for this request app.service('messages').create(messages, { adapter: { multi: true } }) ```
If the adapter has a `Model` option, `params.adapter.Model` can be used to point to different databases based on the request to e.g. allow multi-tenant systems. This is usually done by setting `context.params.adapter` in a [hook](../hooks.md).## params.paginate Setting `paginate` in the [service method `params`](../services.md#params) allows to change or disable the default pagination for a single request: ```ts // Get all messages as an array const allMessages = await app.service('messages').find({ paginate: false }) ``` ## Extending Adapters There are two ways to extend existing database adapters. Either by extending the base class or by adding functionality through hooks. ### Classes All modules also export an [ES6 class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes) as `
These methods are only available internally on the server, not on the client side and only for the Feathers database adapters. They do _not_ send any events.### adapter.find(params) `adapter.find(params) -> Promise` returns a list of all records matching the query in `params.query` using the [common querying mechanism](./querying.md). Will either return an array with the results or a page object if [pagination is enabled](#pagination). ```ts // Find all messages for user with id 1 const messages = await app.service('messages').find({ query: { userId: 1 } }) console.log(messages) // Find all messages belonging to room 1 or 3 const roomMessages = await app.service('messages').find({ query: { roomId: { $in: [1, 3] } } }) console.log(roomMessages) ``` Find all messages for user with id 1 ``` GET /messages?userId=1 ``` Find all messages belonging to room 1 or 3 ``` GET /messages?roomId[$in]=1&roomId[$in]=3 ``` ### adapter.get(id, params) `adapter.get(id, params) -> Promise` retrieves a single record by its unique identifier (the field set in the `id` option during initialization). ```ts const message = await app.service('messages').get(1) console.log(message) ``` ``` GET /messages/1 ``` ### adapter.create(data, params) `adapter.create(data, params) -> Promise` creates a new record with `data`. `data` can also be an array to create multiple records. ```ts const message = await app.service('messages').create({ text: 'A test message' }) console.log(message) const messages = await app.service('messages').create([ { text: 'Hi' }, { text: 'How are you' } ]) console.log(messages) ``` ``` POST /messages { "text": "A test message" } ``` ### adapter.update(id, data, params) `adapter.update(id, data, params) -> Promise` completely replaces a single record identified by `id` with `data`. Does not allow replacing multiple records (`id` can't be `null`). `id` can not be changed. ```ts const updatedMessage = await app.service('messages').update(1, { text: 'Updates message' }) console.log(updatedMessage) ``` ``` PUT /messages/1 { "text": "Updated message" } ``` ### adapter.patch(id, data, params) `adapter.patch(id, data, params) -> Promise` merges a record identified by `id` with `data`. `id` can be `null` to allow replacing multiple records (all records that match `params.query` the same as in `.find`). `id` can not be changed. ```ts const patchedMessage = await app.service('messages').patch(1, { text: 'A patched message' }) console.log(patchedMessage) const params = { query: { read: false } } // Mark all unread messages as read const multiPatchedMessages = await app.service('messages').patch( null, { read: true }, params ) ``` ``` PATCH /messages/1 { "text": "A patched message" } ``` Mark all unread messages as read ``` PATCH /messages?read=false { "read": true } ``` ### adapter.remove(id, params) `adapter.remove(id, params) -> Promise` removes a record identified by `id`. `id` can be `null` to allow removing multiple records (all records that match `params.query` the same as in `.find`). ```ts const removedMessage = await app.service('messages').remove(1) console.log(removedMessage) const params = { query: { read: true } } // Remove all read messages const removedMessages = await app.service('messages').remove(null, params) ``` ``` DELETE /messages/1 ``` Remove all read messages ``` DELETE /messages?read=true ```