Socket
Book a DemoInstallSign in
Socket

apollo-connector-mongodb

Package Overview
Dependencies
Maintainers
1
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apollo-connector-mongodb

Apollo connector for mongodb

3.1.1
latest
npmnpm
Version published
Weekly downloads
1
Maintainers
1
Weekly downloads
 
Created
Source

Introduction

Connector for mongodb, focues on its use with GraphQL (Apollo) and facilitates:

  • Mongo connection
  • Result caching - Entities use Facebook's DataLoader to handle batch processing and caching of query results
  • Unit testing - handy withEntity function provides seamless API for unit and integration testing

This module is built in ES6 with commonjs modules. You have to use Node 6+ to use it.

Breaking Changes

  • Using mongodb 4.0
  • find function using standard API

Quick Start

import { MongoConnector, MongoEntity } from 'apollo-connector-mongodb');
import lruCache from 'lru-cache';

const mongoURL = 'mongodb://localshot:27017/test';

const conn = new MongoConnector(mongoURL, () => {
  
  // create your entities (collections)
  const users = new MongoEntity(conn, 'users', { cacheMap: lruCache });
  const context = {
    users
  }

  //init express and apollo
  const config = {
    schema,
    context
  };

  // launches a new express instance
  startExpress(config);
});

API

MongoEntity provides following functions:

  • find(selector: Object, fields?: Object, skip?: number, limit?: number, timeout?: number): Cursor<T>
  • findOne(selector: Object, options?: FindOneOptions): Promise<T>
  • findOneCached(loader: DataLoader<string, T>, key: string, fieldSelector?: Object): Promise<T> - finds a record using a efined loader and inserts it into cache, with selector you can further filter returned fields
  • findOneCachedById(id: string, fieldSelector?: Object): Promise<T>
  • findManyCached(loader: DataLoader<string, T[]>, key: string, fieldSelector?: Object): Promise<T[]>
  • findAllCached(fieldSelector?: Object): Promise<T[]>
  • insert(document: T): Promise<InsertOneWriteOpResult> - also invalidates insert caches
  • insertMany(document: T[]): Promise<InsertOneWriteOpResult> - also invalidates insert caches
  • delete(selector: Object, many = false): Promise<DeleteWriteOpResultObject> - also invalidates insert caches
  • update(selector: Object, update: Object, options?: ReplaceOneOptions): Promise<UpdateWriteOpResult> - also invalidates update caches

Example

const users = new MongoEntity(conn, 'users', { cacheMap: lruCache });
const user = await users.findOneCachedById('1', { profile: 1, email: 1 });

Unit Testing

MongoEntity provides a handy withEntity function that facilitates unit testing.

We are going to test a following implementation of GraphQL Apollo query:

solution(root: any, { scheduleId, practicalId, exerciseId, userId }: any, { user, access, solutions }: App.Server.Context): Promise<App.Collections.ISolutionDAO> {
  if (access.playsRoles(user, ['admin', 'tutor'])) {
    // admin or tutor possibly view their own solutions
    userId = userId ? userId : user._id;
  } else {
    // non admins and tutors are bound to see their own solutions
    userId = user._id;
  }
  return solutions.solution(scheduleId, practicalId, exerciseId, userId);
}

And here is the test

import { withEntity } from 'apollo-connector-mongodb';
import sinon from 'sinon';

describe('Solution Schema', () => {
  describe('Queries', () => {
    describe('solution', () => {
      it ('returns solution of a given user for admin and tutor, otherwise only from server user. @integration', async () => {
        await withEntity(async (solutions) => {
          // init context
          const context {
            user: { _id: 1 },
            solutions,
            access: { playsRoles: sinon.stub().returns(false); }
          };

          // setup
          await solutions.insertMany([
            { scheduleId: 1, practicalId: 2, exerciseId: 3, userId: 1 },
            { scheduleId: 1, practicalId: 2, exerciseId: 3, userId: 2 }
          ]);

          // query for someone elses work
          const params = { scheduleId: 1, practicalId: 2, exerciseId: 3, userId: 4 };
          const prohibitedResult = await solutionSchema.queries.solution(null, params, context);

          // it returns user result instead
          expect(prohibitedResult).to.deep.equal({ scheduleId: 1, practicalId: 2, exerciseId: 3, userId: 1 });
        }, { entities: [{ type: SolutionsModel }]});
      })
    });
  });
});

Please note that no database initialisation is necessary, everything is handled automatically. Even creation of the test database and it's deletion. Following is the definition of withEntity functions and the realted options:

interface TestOption<T> {
  // data to be inserted before the test
  data?: T[];
  // collection name
  name?: string;
  // custom entity type (child of MongoEntity) 
  type: any,
  // exisitng instance of MongoEntity
  entity?: MongoEntity<T>;
}
interface TestOptions {
  entities?: TestOption<any>[];
}


withEntity<T>(test: (...entity: MongoEntity<T>[]) => any, options?: TestOptions): Promise<any>;

Custom Entitites

Entities should serve as base model for your custom models

class User extends MongoEntity {
  method() {
    this.collection.find() ... // mogodb collection
  }
}

Keywords

Apollo

FAQs

Package last updated on 18 Aug 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.