- Base Provider Methods
- Read
- Update
- Create
- Delete
- Aggregation
- Transactions
- Other Options / Helpers
- A Note on Permissions / Auth
Graphweaver allows users to connect many data sources together. Many datasources are included as a part of our open source repo and a few are a part of our enterprise repo. If you want to connect to something we don’t already have a provider for, you can create your own data integration and extend the Graphweaver’s functionality.
There’s nothing special to inherit from, you just need to comply with the BackendProvider interface. If you’d like to start from a base class that implements everything with stub methods that throw Not Implemented
use the BaseDataProvider here. A minimal example looks like this:
import { BaseDataProvider, Entity, Field, ID } from "@exogee/graphweaver";
import Graphweaver from "@exogee/graphweaver-server";
class MyProvider extends BaseDataProvider<any> {
constructor() {
super("MyProvider");
}
public async find(filter) {
return Promise.resolve([{ id: "1", magicWord: "orange" }]);
}
public async findOne(filter) {
return Promise.resolve({ id: "1", magicWord: "orange" });
}
}
@Entity("Test", {
provider: new MyProvider(),
})
export class Test {
@Field(() => ID)
id!: string;
@Field(() => String)
magicWord!: string;
}
export const graphweaver = new Graphweaver();
With this, the admin area will display as follows:
Base Provider Methods
The following methods can be implemented. D
in these types refers to the generic type argument passed to BaseDataProvider
or BackendProvider
, which represents the data object returned by your provider. G
in these types refers to the GraphQL Entity (in the schema
folder) shape.
Read
find(filter: Filter<D>, pagination?: PaginationOptions): Promise<D[]>;
find
accepts arguments for filtering and pagination. find
returns an array of the entities that match the filter and pagination params.
findOne(filter: Filter<D>): Promise<D | null>;
findOne
accepts a filter with the id of the entity being loaded and returns a single entity.
findByRelatedId(
entity: Constructor<G>,
relatedField: string,
relatedIds: readonly string[],
filter?: Filter<D>
): Promise<D[]>;
findByRelatedId
gets entities by id that are related to the parent entity. This is called when Graphweaver is joining and using DataLoader to load related entities across a relationship.
Update
updateOne(id: string | number, updateArgs: Partial<D>): Promise<D>;
updateOne
updates an entity with the primary key specified with a payload. This is called when someone runs the update[entity name]
mutation.
updateMany(entities: Partial<D>[]): Promise<D[]>;
updateMany
updates multiple entities with a specified payload. The primary key for each entity that needs updating is in the payload.
Create
createOne(entity: Partial<D>): Promise<D>;
createOne
- Create an entity with the given payload, return the entity created.
createMany(entities: Partial<D>[]): Promise<D[]>;
createMany
- Create multiple entities from an array of entity payloads, return the entities that were created.
createOrUpdateMany(entities: Partial<D>[]): Promise<D[]>;
createOrUpdateMany
- Create or update entities in the payload. If the primary key is present in the payload for the entity, the operation is an update. If it is absent, it’s a create. Return the entities that were created and/or updated.
Delete
deleteOne(filter: Filter<D>): Promise<boolean>;
deleteOne
- Delete the entity that matches the filter. Return whether the operation was successful or not. If no entity was deleted but the operation successfully talked to the backend store, you should return false
.
deleteMany?(filter: Filter<D>): Promise<boolean>;
deleteMany
- Delete the entities that match the filter. Returns a boolean indicating whether rows were deleted or not.
Aggregation
aggregate?(
filter: Filter<D> | undefined,
requestedAggregations: Set<AggregationType>
): Promise<AggregationResult>;
aggregate
is an optional method. If implemented, then Graphweaver will generate [yourEntity]_aggregate
queries for your entities. When users request an aggregation result, this method will get called with the filter parameter passed by the user and a Set
of requested aggregation types. For example this query:
query {
tasks_aggregate {
count
}
}
Will end up calling the provider for the Task
entity with AggregationType.COUNT
and no filter.
Transactions
If you’re working with something that supports transactions, you can implement
withTransaction?: <T>(callback: () => Promise<T>) => Promise<T>;
This will get called when multiple operations happen in the same server call so that you can batch them into a single transaction and roll back if anything fails.
Other Options / Helpers
There are some other options and helpers that are explained in the BackendProvider interface in core/src/types.ts.
A Note on Permissions / Auth
If ACLs are specified that block the request, your provider will not get queried at all.
If row level security is specified, these filters will be passed to you to handle in the provider methods. If you do not implement filtering correctly, then row level security ACLs will not work for entities that are managed by your provider.