-
Notifications
You must be signed in to change notification settings - Fork 7
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
Changes from all commits
1a195d2
c5358bf
ca88bc5
23d6c4f
600c42b
d6fa6ed
3cb4c95
61450db
f4d8462
9276d36
5a26ef2
88bac39
16c072e
0b605aa
c0d55a5
ce300d1
c9e760c
14e6838
8b71038
08f89e9
0fb676a
75f21c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,4 +56,5 @@ typings/ | |
|
||
# dotenv environment variables file | ||
.env | ||
|
||
lib | ||
data |
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' }), | ||
}, | ||
}, | ||
}; | ||
|
||
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. |
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 |
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 |
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" | ||
} | ||
} |
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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); |
There was a problem hiding this comment.
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.