apollo-model-mongodb BETA
Description
This package allows you to automatically generate Apollo Server schema and resolvers for MongoDB using Prisma-like SDL.
We like Prisma but we want to build a more flexible and customizable solution.
Quick preview on codesandbox
Note! The database connected with read-only permissions. So mutation will not work. You can create and connect your own database (for example use Atlas)
Installation
With yarn:
yarn add apollo-model-mongodb
or using npm:
npm install --save apollo-model-mongodb
Usage
Project initialization is the same as for Apollo Server. The only difference is that we use makeExecutableSchema
from this package to generate schema.
;const schema = await queryExecutor: ; const server = schema;
You can find full examples here
SDL example
type Category @model { id: ObjectID! @id @unique @db(name: "_id") title: String @default(value: "New Category") parentCategory: Category @relation(storeField: "parentCategoryId") subcategories: [Category!] @extRelation(storeField: "parentCategoryId") posts: [Post!] @extRelation createdAt: Date @createdAt updatedAt: Date @updatedAt} type Comment { body: String user: User! @relation} type Post @model { id: ObjectID! @id @unique @db(name: "_id") title: String! body: String! category: Category @relation keywords: [String!] owner: User! @relation place: GeoJSONPoint comments: [Comment!]} interface User @inherit @model { id: ObjectID! @id @unique @db(name: "_id") username: String! @unique} enum AdminRole { superadmin moderator} type Admin implements User { role: AdminRole} enum SubscriberRole { free standard premium} type SubscriberProfile { firstName: String! lastName: String!} type Subscriber implements User { role: SubscriberRole profile: SubscriberProfile!}
The above SDL generates this endpoint https://apollo-model-mongodb-example.now.sh
Example queries below
Directives
model
directive
The - Connects object with MongoDB collection.
- Valid locations: OBJECT or INTERFACE
- Optional
- Arguments
- collection:String
- The name of MongoDB collection * Optional (Default value is pluralized name of the object)
unique
directive
The - Add field to WHERE_UNIQUE input type
- Valid locations: FIELD
- Optional
id
directive
The - Mark field as identifier. Skip creation.
- Valid locations: FIELD
- Optional
db
directive
The - Map GraphQL field to collection.
- Valid locations: FIELD
- Optional
- Arguments
- name:String
- The name of field in collection * Required
default
directive
The - Sets a default value for a field.
- Valid locations: FIELD
- Optional
- Arguments
- value:String
- The default value for the field * Required
inherit
directive
The - Clones interface fields to objects.
- Valid locations: INTERFACE
- Required
discriminator
directive
The - Used to define field and values to resolve implementation type.
- Valid locations: INTERFACE or OBJECT
- Optional
- Arguments
- value:String
- Required
relation
directive
The - Used to define relation between two collections.
- Valid locations: FIELD
- Optional
- Arguments
- field:String
- Optional
- Default value: _id
- storeField:String
- Optional
- Default value:
${TypeName}Id${s}
extRelation
directive
The -
Used to define external relation between two collections (identifiers stored in related documents).
-
Valid locations: FIELD
-
Optional
-
Arguments
-
field:String
- Optional
- Default value: _id
-
storeField:String
- Optional
- Default value:
${TypeName}Id${s}
-
many:Boolean
- Optional
- Default value: false
-
createdAt
directive
The - Sets date on field on CREATE.
- Valid locations: FIELD
- Optional
updatedAt
directive
The - Sets date on field on CREATE and UPDATE.
- Valid locations: FIELD
Serverless
You can use this package with serverless environments. Read more here. Also take a look at example-now if you are using Zeit Now.
Customization
- You can define your own scalars and directives as for usual Apollo server.
- You can add custom modules at MongoModel stage (docs coming soon)
- All queries to DB executes with QueryExecutor function. This package has predefined one, but you can override it and add hooks or check user authorization.
const QueryExecutor = ({ type, collection, doc, docs, selector, options })=>Promise
Contribution
You are welcome to open Issues, Feature Requests and PR with new features and bug fixes
Roadmap
- Filter by Nth array element
- Add subscriptions
- Release stable version 1.0.0
- Add Moment scalar
- Improve Geo queries support
Features
- Simple query
- Simple create
- Filter
- Difficult filter
- Relation query
- Relation filter
- Relation create
- Nested create
- Interfaces
- Geo queries
Simple query
query
{ categories { id title }}
response
Simple create
query
mutation { createCategory(data: { title: "root" }) { id }}
response
Filter
request
{ categories(where: { title: "root" }) { id title }}
response
Difficult filter
request
{ categories(where: { OR: [{ title: "root" }, { title: "JS" }] }) { id title }}
response
Relation query
query
{ categories { id title parentCategory { title } }}
response
Relation filter
query
{ categories(where: { parentCategory: { title: "root" } }) { id title }}
response
Relation create
query
mutation { createCategory( data: { title: "Mongodb" parentCategory: { connect: { id: "5c3f4d84e98bd4e76e1d34d1" } } } ) { id }}
response
Nested create
query
mutation { createSubscriber( data: { username: "subscriber1" profile: { create: { firstName: "Gwion", lastName: "Britt" } } } ) { id username }}
response
Interfaces
Connect
query
mutation { createPost( data: { title: "Build GraphQL API with Apollo" body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit." owner: { connect: { Admin: { username: "admin" } } } } ) { id }}
response
Query
query
{ posts { title owner { username ... on Subscriber { profile { firstName lastName } } } }}
response
Geo queries
query
{ posts( where: { place_near: { geometry: { type: Point, coordinates: [0, 51.01] } maxDistance: 10000 } } ) { id title place { distance(toPoint: { type: Point, coordinates: [0, 51.01] }) } }}
response