apollo-model-mongodb

0.4.5 • Public • Published

apollo-model-mongodb BETA

Build Status

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.

Join the community on Spectrum

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)

Edit apollo-model-mongodb-example

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.

import ApolloModelMongo, { QueryExecutor } from 'apollo-model-mongodb';
const schema = await new ApolloModelMongo({
  queryExecutor: QueryExecutor(db),
}).makeExecutablSchema({
  typeDefs,
});
 
const server = new ApolloServer({
  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

The model directive

  • 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)

The unique directive

  • Add field to WHERE_UNIQUE input type
  • Valid locations: FIELD
  • Optional

The id directive

  • Mark field as identifier. Skip creation.
  • Valid locations: FIELD
  • Optional

The db directive

  • Map GraphQL field to collection.
  • Valid locations: FIELD
  • Optional
  • Arguments
    • name:String
    • The name of field in collection * Required

The default directive

  • Sets a default value for a field.
  • Valid locations: FIELD
  • Optional
  • Arguments
    • value:String
    • The default value for the field * Required

The inherit directive

  • Clones interface fields to objects.
  • Valid locations: INTERFACE
  • Required

The discriminator directive

  • Used to define field and values to resolve implementation type.
  • Valid locations: INTERFACE or OBJECT
  • Optional
  • Arguments
    • value:String
    • Required

The relation directive

  • 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}

The extRelation directive

  • 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

The createdAt directive

  • Sets date on field on CREATE.
  • Valid locations: FIELD
  • Optional

The updatedAt directive

  • 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

query
{
  categories {
    id
    title
  }
}
response
{
  "data": {
    "categories": [
      {
        "id": "5c3f4d84e98bd4e76e1d34d1",
        "title": "root"
      },
      {
        "id": "5c3f4dd3e98bd4e76e1d34d2",
        "title": "JS"
      },
      {
        "id": "5c3f4f46e98bd4e76e1d34d3",
        "title": "MongoDB"
      }
    ]
  }
}

Simple create

query
mutation {
  createCategory(data: { title: "root" }) {
    id
  }
}
response
{
  "data": {
    "createCategory": {
      "id": "5c3f4d84e98bd4e76e1d34d1"
    }
  }
}

Filter

request
{
  categories(where: { title: "root" }) {
    id
    title
  }
}

response

{
  "data": {
    "categories": [
      {
        "id": "5c3f4d84e98bd4e76e1d34d1",
        "title": "root"
      }
    ]
  }
}

Difficult filter

request
{
  categories(where: { OR: [{ title: "root" }, { title: "JS" }] }) {
    id
    title
  }
}

response

{
  "data": {
    "categories": [
      {
        "id": "5c3f4d84e98bd4e76e1d34d1",
        "title": "root"
      },
      {
        "id": "5c3f4dd3e98bd4e76e1d34d2",
        "title": "JS"
      }
    ]
  }
}

Relation query

query
{
  categories {
    id
    title
    parentCategory {
      title
    }
  }
}
response
{
  "data": {
    "categories": [
      {
        "id": "5c3f4d84e98bd4e76e1d34d1",
        "title": "root",
        "parentCategory": null
      },
      {
        "id": "5c3f4dd3e98bd4e76e1d34d2",
        "title": "JS",
        "parentCategory": {
          "title": "root"
        }
      },
      {
        "id": "5c3f4f46e98bd4e76e1d34d3",
        "title": "MongoDB",
        "parentCategory": {
          "title": "root"
        }
      }
    ]
  }
}

Relation filter

query
{
  categories(where: { parentCategory: { title: "root" } }) {
    id
    title
  }
}
response
{
  "data": {
    "categories": [
      {
        "id": "5c3f4dd3e98bd4e76e1d34d2",
        "title": "JS"
      },
      {
        "id": "5c3f4f46e98bd4e76e1d34d3",
        "title": "MongoDB"
      }
    ]
  }
}

Relation create

query
mutation {
  createCategory(
    data: {
      title: "Mongodb"
      parentCategory: { connect: { id: "5c3f4d84e98bd4e76e1d34d1" } }
    }
  ) {
    id
  }
}
response
{
  "data": {
    "createCategory": {
      "id": "5c3f4f46e98bd4e76e1d34d3"
    }
  }
}

Nested create

query
mutation {
  createSubscriber(
    data: {
      username: "subscriber1"
      profile: { create: { firstName: "Gwion", lastName: "Britt" } }
    }
  ) {
    id
    username
  }
}
response
{
  "data": {
    "createSubscriber": {
      "id": "5c3f555b190d25e7bda1dea2",
      "username": "subscriber1"
    }
  }
}

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
{
  "data": {
    "createPost": {
      "id": "5c401347de7e67e9540abad2"
    }
  }
}

Query

query
{
  posts {
    title
    owner {
      username
      ... on Subscriber {
        profile {
          firstName
          lastName
        }
      }
    }
  }
}
response
{
  "data": {
    "posts": [
      {
        "title": "Build GraphQL API with Apollo",
        "owner": {
          "username": "admin"
        }
      }
    ]
  }
}

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
{
  "data": {
    "posts": [
      {
        "id": "5c401347de7e67e9540abad2",
        "title": "Build GraphQL API with Apollo",
        "place": {
          "distance": 1111.9492664453662
        }
      }
    ]
  }
}

Dependents (0)

Package Sidebar

Install

npm i apollo-model-mongodb

Weekly Downloads

0

Version

0.4.5

License

ISC

Unpacked Size

444 kB

Total Files

38

Last publish

Collaborators

  • vitramir