# @graphex/core

> ![](cover/cover.jpg)

Latest version **1.2.4** (published 2021-06-14) · ISC license · 0 weekly downloads

## Install

```sh
npm install @graphex/core
pnpm add @graphex/core
yarn add @graphex/core
bun add @graphex/core
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned.

## Facts

| | |
|---|---|
| Version | 1.2.4 |
| Published | 2021-06-14 |
| First published | 2021-06-02 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 14 |
| Unpacked size | 428.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 16 |
| Maintainers | antt001, vitramir |
| Keywords | apollo, mongodb, sdl, model, autogenerate |

## Links

- npm: https://www.npmjs.com/package/@graphex/core
- Repository: https://github.com/vitramir/apollo-model-mongodb
- Issues: https://github.com/vitramir/apollo-model-mongodb/issues
- npm.io page: https://npm.io/package/@graphex/core

## Dependencies (14)

- [ramda](https://npm.io/package/ramda.md) ^0.27.0
- [lodash](https://npm.io/package/lodash.md) ^4.17.11
- [pluralize](https://npm.io/package/pluralize.md) ^7.0.0
- [dataloader](https://npm.io/package/dataloader.md) ^1.4.0
- [graphql-tag](https://npm.io/package/graphql-tag.md) ^2.10.1
- [object-hash](https://npm.io/package/object-hash.md) ^1.3.1
- [graphql-tools](https://npm.io/package/graphql-tools.md) ^4.0.5
- [@babel/runtime](https://npm.io/package/@babel/runtime.md) ^7.2.0
- [graphql-resolvers](https://npm.io/package/graphql-resolvers.md) ^0.2.2
- [@apollo/federation](https://npm.io/package/@apollo/federation.md) ^0.25.1
- [@graphex/type-wrap](https://npm.io/package/@graphex/type-wrap.md) 1.0.0
- [@graphex/ast-from-value](https://npm.io/package/@graphex/ast-from-value.md) 1.0.0
- [@graphex/mongodb-executor](https://npm.io/package/@graphex/mongodb-executor.md) 1.0.0
- [@graphex/directive-inherit](https://npm.io/package/@graphex/directive-inherit.md) 1.0.0

## Alternatives

- [angular-pipes](https://npm.io/package/angular-pipes.md) — 5.6K weekly downloads
- [@ng-web-apis/midi](https://npm.io/package/@ng-web-apis/midi.md) — 2.6K weekly downloads
- [happn-3](https://npm.io/package/happn-3.md) — 1.6K weekly downloads
- [@opensip-cli/lang-go](https://npm.io/package/@opensip-cli/lang-go.md) — 1.2K weekly downloads
- [mongoose-typescript](https://npm.io/package/mongoose-typescript.md) — 85 weekly downloads

## Recent versions

- 1.2.4 (latest) — 2021-06-14
- 1.2.3 — 2021-06-11
- 1.2.2 — 2021-06-10
- 1.2.1 — 2021-06-08
- 1.2.0 — 2021-06-07
- 1.1.0 — 2021-06-07
- 1.0.1 — 2021-06-07
- 1.0.0 — 2021-06-06
- 0.8.0 — 2021-06-02
- 0.7.0 — 2021-06-02
- 0.7.0-alpha.3 — 2021-06-02
- 0.7.0-alpha.0 — 2021-06-02

## README

# Graphex Core

![](cover/cover.jpg)

![Build Status](https://gitlab.com/graphexio/graphex/badges/master/pipeline.svg)

## Description

This package allows you to automatically generate Apollo Server schema and resolvers for MongoDB using Prisma-like SDL.

## Quick preview on codesandbox

Note!
In Codesandbox any change in the code will restart the service. In this setup we use in memory DB, hence any restart will purge the data you'll create with Mutations

[![Edit graphex-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/graphexio/graphex/tree/master/packages/example-server)

## Installation

With yarn:

```
yarn add @graphex/core
```

or using npm:

```
npm install --save @graphex/core
```

## Usage

Project initialization is the same as for [Apollo Server](https://www.apollographql.com/docs/apollo-server/getting-started.html). The only difference is that we use `makeExecutableSchema` from this package to generate schema.

```javascript
import ApolloModelMongo, { QueryExecutor } from '@graphex/core';
const schema = await new ApolloModelMongo({
  queryExecutor: QueryExecutor(db),
}).makeExecutablSchema({
  typeDefs,
});

const server = new ApolloServer({
  schema,
});
```

You can find full examples [here](examples)

## SDL example

```graphql
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](https://apollo-model-mongodb-example.now.sh)

Example queries [below](#features)

## 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](https://www.apollographql.com/docs/apollo-server/servers/lambda.html). Also take a look at [example-now](examples/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-query)
- [Simple create](#simple-create)
- [Filter](#filter)
- [Difficult filter](#difficult-filter)
- [Relation query](#relation-query)
- [Relation filter](#relation-filter)
- [Relation create](#relation-create)
- [Nested create](#nested-create)
- [Interfaces](#interfaces)
- [Geo queries](#geo-queries)

### Simple query

##### query

```graphql
{
  categories {
    id
    title
  }
}
```

##### response

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

### Simple create

##### query

```graphql
mutation {
  createCategory(data: { title: "root" }) {
    id
  }
}
```

##### response

```json
{
  "data": {
    "createCategory": {
      "id": "5c3f4d84e98bd4e76e1d34d1"
    }
  }
}
```

### Filter

##### request

```graphql
{
  categories(where: { title: "root" }) {
    id
    title
  }
}
```

#### response

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

### Difficult filter

##### request

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

#### response

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

### Relation query

##### query

```graphql
{
  categories {
    id
    title
    parentCategory {
      title
    }
  }
}
```

##### response

```json
{
  "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

```graphql
{
  categories(where: { parentCategory: { title: "root" } }) {
    id
    title
  }
}
```

##### response

```json
{
  "data": {
    "categories": [
      {
        "id": "5c3f4dd3e98bd4e76e1d34d2",
        "title": "JS"
      },
      {
        "id": "5c3f4f46e98bd4e76e1d34d3",
        "title": "MongoDB"
      }
    ]
  }
}
```

### Relation create

##### query

```graphql
mutation {
  createCategory(
    data: {
      title: "Mongodb"
      parentCategory: { connect: { id: "5c3f4d84e98bd4e76e1d34d1" } }
    }
  ) {
    id
  }
}
```

##### response

```json
{
  "data": {
    "createCategory": {
      "id": "5c3f4f46e98bd4e76e1d34d3"
    }
  }
}
```

### Nested create

##### query

```graphql
mutation {
  createSubscriber(
    data: {
      username: "subscriber1"
      profile: { create: { firstName: "Gwion", lastName: "Britt" } }
    }
  ) {
    id
    username
  }
}
```

##### response

```json
{
  "data": {
    "createSubscriber": {
      "id": "5c3f555b190d25e7bda1dea2",
      "username": "subscriber1"
    }
  }
}
```

### Interfaces

#### Connect

##### query

```graphql
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

```json
{
  "data": {
    "createPost": {
      "id": "5c401347de7e67e9540abad2"
    }
  }
}
```

#### Query

##### query

```graphql
{
  posts {
    title
    owner {
      username
      ... on Subscriber {
        profile {
          firstName
          lastName
        }
      }
    }
  }
}
```

##### response

```json
{
  "data": {
    "posts": [
      {
        "title": "Build GraphQL API with Apollo",
        "owner": {
          "username": "admin"
        }
      }
    ]
  }
}
```

### Geo queries

##### query

```graphql
{
  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

```json
{
  "data": {
    "posts": [
      {
        "id": "5c401347de7e67e9540abad2",
        "title": "Build GraphQL API with Apollo",
        "place": {
          "distance": 1111.9492664453662
        }
      }
    ]
  }
}
```

---
_Source: https://npm.io/package/@graphex/core · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
