npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

apollo-model-mongodb

v0.4.5

Published

![](cover/cover.jpg)

Downloads

20

Readme

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