Skip to content

Generate CRUD typeDefs and resolvers for a type that is annotated with @model directive #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Mar 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
1a195d2
feat(model directive): Add id field to a type
TimMikeladze Mar 9, 2018
c5358bf
feat(model directive): Generate queries and mutations typeDefs. Addit…
TimMikeladze Mar 9, 2018
ca88bc5
feat(storage): Storage interface
TimMikeladze Mar 9, 2018
23d6c4f
feat(monorepo): Create mongo repo and move graphql-model-directive to…
TimMikeladze Mar 10, 2018
600c42b
feat(mongo): Began implementing MongoStorage functions. findOne and c…
TimMikeladze Mar 10, 2018
d6fa6ed
docs(readme): Updated getting started steps
TimMikeladze Mar 10, 2018
3cb4c95
feat(misc): Variety of fixes and improvements
TimMikeladze Mar 10, 2018
61450db
feat(example): Setup simple example
TimMikeladze Mar 10, 2018
f4d8462
feat(model directive): generate input types
TimMikeladze Mar 11, 2018
9276d36
feat(misc): Move graphql packages to mono repo root. Add isDeprecated…
TimMikeladze Mar 17, 2018
5a26ef2
chore(docker): Added docker-compose.yml with Mongo service
TimMikeladze Mar 17, 2018
88bac39
feat(model directive): Hooked up create and findOne mutations to stor…
TimMikeladze Mar 17, 2018
16c072e
feat(model directive): Added support for find many queries
TimMikeladze Mar 17, 2018
0b605aa
feat(model directive): Tests for find many
TimMikeladze Mar 17, 2018
c0d55a5
feat(model directive): Added support for update
TimMikeladze Mar 17, 2018
ce300d1
feat(model directive): Added suppport for upsert
TimMikeladze Mar 17, 2018
c9e760c
feat(model directive): Add support for remove
TimMikeladze Mar 17, 2018
14e6838
docs(readme): Updated readme
TimMikeladze Mar 17, 2018
8b71038
docs(license): Added license
TimMikeladze Mar 17, 2018
08f89e9
feat(model directive): Generate input types given an object type. Clo…
TimMikeladze Mar 18, 2018
0fb676a
Merge branch 'issue-15-input-types' into dev
TimMikeladze Mar 18, 2018
75f21c0
chore(rename packages): Renamed to graphql-crud and graphql-crud-mongo
TimMikeladze Mar 23, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,5 @@ typings/

# dotenv environment variables file
.env

lib
data
130 changes: 128 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,128 @@
# graphql-model-directive
Connect a GraphQL schema to a database. Generates additional type definitions and resolvers using directives.
# graphql-crud

**Note: this package is under active development**

GraphQL schema directives to generate CRUD queries, mutations and resolvers which are automatically connected to a database.

**Supported databases:**

- Mongo

**Available directives:**

- `@model` - Generates queries, mutations and resolvers for the annotated type.

## Getting started

1. Install core package: `npm install graphql-crud` or `yarn add graphql-crud`.
2. Install a store package:
- Mongo: `npm install graphql-crud-mongo` or `yarn add graphql-crud-mongo`.
3. Define your schema and annotate it with directives.
4. Use `makeExecutableSchema` to generate the schema.
5. Instantiate and assign your store to `directives.model.store` on the GraphQL `context`.

```javascript
import { makeExecutableSchema } from 'graphql-tools';
import { execute } from 'graphql';
import gql from 'graphql-tag';
import crud from 'graphql-crud';
import MongoStore from 'graphql-crud-mongo';
import typeDefs from './typeDefs';

const typeDefs = `

type Item @model {
name: String
}

type Mutation {
_: Boolean
}

type Query {
_: Boolean
}
`

const schema = makeExecutableSchema({
typeDefs,
schemaDirectives: {
...crud
},
});

const context = {
directives: {
model: {
store: new MongoStore({ connection: 'mongodb://localhost/my-database' }),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MongoStore isn't imported in this example code.

},
},
};

execute(
schema,
gql`
mutation {
createItem(
data: {
name: "hello world"
}
) {
id
name
}
}
`
null,
context
);
```

The above example will generate the following schema with functioning resolvers.

```graphql
type Item {
name: String
id: ID
}

input ItemInputType {
name: String
id: ID
}

type Mutation {
_: Boolean

createItem(data: ItemInputType): Item
updateItem(data: ItemInputType, where: ItemInputType, upsert: Boolean): Boolean
removeItem(where: ItemInputType): Boolean
}

type Query {
_: Boolean

item(where: ItemInputType): Item
items(where: ItemInputType): [Item]
}
```

## Running the examples

In the repo's root run the following:
1. `docker-compose up -d` to start dependent databases.
1. `npm install` or `yarn install`

In `examples/simple` run the following:

1. `npm install; npm start` or `yarn install; yarn start`
1. Navigate to http://localhost:3000/graphiql


## Getting started for development

1. `docker-compose up -d` to start database dependencies for testing and the example.
1. `npm install` or `yarn install`.
1. `npm run link:packages` or `yarn link:packages`.
1. `npm run build:watch` or `yarn build:watch`
1. Write code.
38 changes: 38 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Javascript Node CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
version: 2
jobs:
build:
docker:
# specify the version you desire here
- image: circleci/node:8.9
- image: mongo

# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/mongo:3.4.4

working_directory: ~/repo

steps:
- checkout

# Download and cache dependencies
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-

- run: yarn install

- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}

# run tests!
- run: yarn test:prod
13 changes: 13 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: '2'
services:
mongodb:
image: mongo:latest
container_name: "mongodb"
environment:
- MONGO_DATA_DIR=/data/db
- MONGO_LOG_DIR=/dev/null
volumes:
- ./data/db:/data/db
ports:
- 27017:27017
command: mongod --smallfiles --logpath=/dev/null # --quiet
59 changes: 59 additions & 0 deletions examples/simple/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"name": "simple-example",
"version": "0.0.1",
"description": "",
"repository": {
"type": "git",
"url": "git+https://github.com/intelight/graphql-crud.git"
},
"author": "Intelight",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
"license": "MIT",
"private": true,
"scripts": {
"start": "nodemon --exec ./node_modules/.bin/ts-node --watch ../../packages --watch . -- ./src/index.ts",
"build": "rimraf lib && tsc --p ./tsconfig.prod.json",
"build:watch": "rimraf lib && tsc -w --p ./tsconfig.prod.json",
"test": "jest --forceExit",
"test:watch": "jest --watch",
"test:prod": "yarn run lint && yarn run test --coverage --no-cache",
"lint": "tslint --project ./tsconfig.json 'src/**/*.{ts,tsx}' && tslint --project ./tsconfig.json 'test/**/*.{ts,tsx}'"
},
"engines": {
"node": ">=8.9.0"
},
"jest": {
"transform": {
".(ts|tsx)": "../../node_modules/ts-jest/preprocessor.js"
},
"testMatch": [
"<rootDir>/test/**/?(*.)(test).(ts|js)?(x)"
],
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"json"
],
"collectCoverageFrom": [
"test/**/*.{js,jsx,ts,tsx}"
]
},
"devDependencies": {
"@intelight/tslint": "0.0.9",
"@types/graphql": "0.12.4",
"jest": "22.4.2",
"nodemon": "^1.17.1",
"rimraf": "2.6.2",
"ts-jest": "22.4.1",
"ts-node": "5.0.1",
"tslint": "5.9.1",
"typescript": "2.7.2"
},
"dependencies": {
"apollo-server-express": "^1.3.2",
"body-parser": "^1.18.2",
"express": "^4.16.2"
}
}
49 changes: 49 additions & 0 deletions examples/simple/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { graphiqlExpress, graphqlExpress } from 'apollo-server-express';
import * as bodyParser from 'body-parser';
import * as express from 'express';
import crud from 'graphql-crud';
import MongoStore from 'graphql-crud-mongo';
import { makeExecutableSchema } from 'graphql-tools';

const PORT = 3000;

const typeDefs = `
type Item @model {
name: String
subItem: SubItem
}

type SubItem {
name: String
}

type Query {
_: Boolean
}

type Mutation {
_: Boolean

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lol @ graphql still requiring placeholder fields for an initial type declaration. Why doesn't graphql just let us declare multiple instances of a type and then merge them together? The extend keyword has no useful purpose. Obviously it's not your problem, but it makes me laugh each time I see it.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

graphql/graphql-js#937

I guess there's a solution for it now? I have to investigate further.

}
`;

const schema = makeExecutableSchema({
typeDefs,
schemaDirectives: {
...crud,
},
});

const context = {
directives: {
model: {
store: new MongoStore({ connection: 'mongodb://localhost/my-database' }),
},
},
};

const app = express();

app.use('/graphql', bodyParser.json(), graphqlExpress({ schema, context }));
app.get('/graphiql', graphiqlExpress({ endpointURL: '/graphql' }));

app.listen(PORT);
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading