> For the complete documentation index, see [llms.txt](https://docs.soapjs.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.soapjs.com/components/source.md).

# Source

A **Source** is SoapJS's low-level data-access boundary — one per database collection/table. Adapters and repositories build on it. MongoDB's implementation is `MongoSource`.

> In current code the interface is `Source<DocumentType>` and the MongoDB class is `MongoSource`. (Earlier versions called this component a "collection".)

### Creating a Source

```typescript
import { SoapMongo, MongoSource } from '@soapjs/soap-node-mongo';

const soapMongo = await SoapMongo.create(mongoConfig);
const source = new MongoSource(soapMongo, 'characters');
```

You rarely use a Source directly — wrap it in a `DatabaseContext` with a mapper and hand it to a repository:

```typescript
import { DatabaseContext } from '@soapjs/soap';

const context = new DatabaseContext(source, new CharacterMapper(), soapMongo.sessions);
const repo = new CharacterRepositoryMongo(context);
```

### The Source contract

```typescript
interface Source<DocumentType> {
  find(query?): Promise<DocumentType[]>;
  count(query?): Promise<number>;
  aggregate<T>(query): Promise<T[]>;
  insert(query): Promise<DocumentType[]>;
  update(query): Promise<UpdateStats>;
  remove(query): Promise<RemoveStats>;
  native<ResultType>(query): Promise<ResultType>;   // since @soapjs/soap 0.10 / soap-node-mongo 0.7
}
```

* `find` / `count` accept `FindParams` / `CountParams` (built with `Where`) or a `RepositoryQuery`.
* `aggregate` runs a portable `AggregationParams`.
* `native()` is the **escape hatch** for queries the abstraction can't express — it runs a client-specific query verbatim (see *Using Native Queries*).

### Read/write split

Give each side its own connection — read Source on a replica, write Source on the primary:

```typescript
const writeSource = new MongoSource(soapMongoWrite, 'characters'); // primary
const readSource  = new MongoSource(soapMongoRead, 'characters');  // secondaryPreferred
```

See the [demo](https://github.com/soapjs/soap-node-demo) for a full read/write split.
