Skip to content

Commit a929dcd

Browse files
authored
Merge pull request #46 from LiUGraphQL/add-tool-for-creating-graphql-server
Add tool for creating graphql server
2 parents 36cbad1 + 507ad0d commit a929dcd

File tree

16 files changed

+2648
-2
lines changed

16 files changed

+2648
-2
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
__pycache__/
55
venv*/
66
.cache/
7-
bin/
7+
generated-example-server/

README.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,36 @@
11
# woo.sh
2-
Framework for generating a GraphQL server backed by a database.
2+
Framework for generating an [Apollo GraphQL](https://www.apollographql.com/) based server,
3+
backed by a configurable database.
4+
5+
# Try it out
6+
The example is based on a simplified version of the Star Wars GraphQL schema and requires a running
7+
instance of ArangoDB.
8+
```bash
9+
$ sh ./woo.sh --input example/db-schema/ \
10+
--output ./generated-example-server \
11+
--config example/config.yml \
12+
--driver arangodb \
13+
--custom-api-schema example/custom-api-schema.graphql \
14+
--custom-resolvers example/custom-resolvers.js
15+
16+
$ npm server.js
17+
18+
Waiting for ArangoDB to become available at http://localhost:8529
19+
ArangoDB is now available at http://localhost:8529
20+
Database dev-db deleted: true
21+
Database 'dev-db' created
22+
Collection 'Droid' created
23+
Collection 'Species' created
24+
Collection 'Planet' created
25+
Collection 'Human' created
26+
Collection 'Starship' created
27+
Edge collection 'FriendsEdgeFromDroid' created
28+
Edge collection 'HomeWorldEdgeFromDroid' created
29+
Edge collection 'SpeciesEdgeFromDroid' created
30+
Edge collection 'OriginEdgeFromSpecies' created
31+
Edge collection 'StarshipsEdgeFromHuman' created
32+
Edge collection 'FriendsEdgeFromHuman' created
33+
Edge collection 'HomeWorldEdgeFromHuman' created
34+
Edge collection 'SpeciesEdgeFromHuman' created
35+
GraphQL service ready at: http://localhost:4000/
36+
```

example/config.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
validate:
2+
type_names: PascalCase
3+
field_names: camelCase
4+
enum_values: PascalCase
5+
transform:
6+
type_names: PascalCase
7+
field_names: camelCase
8+
enum_values: uppercase
9+
drop_comments: true
10+
generation:
11+
add_query_type: true
12+
add_mutation_type: true
13+
# add id field to all schema types
14+
field_for_id: true
15+
# add creation date and last update date field(s) to all schema types
16+
generate_datetime: true
17+
field_for_creation_date: true
18+
field_for_last_update_date: true
19+
# add reverse edges for traversal
20+
reverse_edges: true
21+
# add edge types
22+
edge_types: false
23+
fields_for_edge_types: false
24+
# add queries
25+
query_by_id: true
26+
query_type_filter: true
27+
query_list_of: true
28+
query_by_key: true
29+
# add input types
30+
input_to_create_objects: true
31+
input_to_update_objects: true
32+
# add edge input types (update not supported)
33+
input_to_create_edge_objects: true
34+
input_to_update_edge_objects: false
35+
# add mutations
36+
create_objects: true
37+
update_objects: true
38+
delete_objects: false
39+
# add edge mutations (update and delete not supported)
40+
create_edge_objects: true
41+
update_edge_objects: false
42+
delete_edge_objects: false

example/custom-api-schema.graphql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
extend type Query {
2+
hello: String!
3+
}

example/custom-resolvers.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports = {
2+
get: function(options) {
3+
return {
4+
Query: {
5+
hello: async (parent, args, context, info) => "Custom function says hello!"
6+
}
7+
};
8+
}
9+
};
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
enum Episode {
2+
NEWHOPE
3+
EMPIRE
4+
JEDI
5+
}
6+
7+
interface Character {
8+
name: String
9+
friends: [Character]
10+
homeWorld: Planet
11+
species: Species
12+
}
13+
14+
type Human implements Character {
15+
name: String!
16+
friends: [Character]
17+
homeWorld: Planet
18+
species: Species
19+
appearsIn: [Episode]!
20+
starships: [Starship]
21+
totalCredits: Int
22+
}
23+
24+
25+
type Droid implements Character {
26+
name: String!
27+
friends: [Character]
28+
homeWorld: Planet
29+
species: Species
30+
appearsIn: [Episode]!
31+
primaryFunction: String
32+
}
33+
34+
type Planet {
35+
name: String
36+
climate: String
37+
}
38+
39+
type Species {
40+
name: String
41+
lifespan: Int
42+
origin: Planet
43+
}
44+
45+
type Starship {
46+
name: String!
47+
length: Float
48+
}

graphql-resolver-generator/generator.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,16 @@ def generate(input_file, output_dir):
3939
'name': camelCase(type_name),
4040
'fields': [],
4141
'edgeFields': [],
42+
'DateTime': [],
4243
'hasKeyDirective': f'_KeyFor{type_name}' in schema.type_map.keys()
4344
}
4445
# add object fields
4546
for field_name, field_type in _type.fields.items():
4647
inner_field_type = get_named_type(field_type.type)
4748
if is_schema_defined_object_type(inner_field_type) or is_interface_type(inner_field_type):
4849
t['fields'].append(field_name)
50+
if inner_field_type.name == 'DateTime':
51+
t['DateTime'].append(field_name)
4952
if field_name[0] == '_':
5053
continue
5154
if is_schema_defined_object_type(inner_field_type) or is_interface_type(inner_field_type):

graphql-resolver-generator/resources/resolver.template

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ const resolvers = {
6767
% for type in data['types']:
6868
${type['Name']}: {
6969
id: (parent, args, context, info) => parent._id,
70+
% for field in type['DateTime']:
71+
${field}: async (parent, args, context, info) => new Date(parent.${field}),
72+
% endfor
7073
% for field in type['fields']:
7174
${field}: async (parent, args, context, info) =>
7275
await driver.getEdge(parent, args, info),

graphql-server/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# graphql-server
2+
This tool is the basis for automatically setting up a GraphQL server, with a configurable
3+
database backend. The GraphQL server is based on [Apollo GraphQL](https://www.apollographql.com/).
4+
Each backend requires a specific `driver`. Different drivers may offer different support when it
5+
comes to e.g. transaction and concurrency support. Refer to the documentation provided for each
6+
driver.
7+
8+
## Drivers
9+
- ArangoDB
10+
11+
## Prerequisites
12+
- npm (Node)
13+
14+
## Example
15+
Generate a `woosh-server` based on a simplified version of the Star Wars GraphQL schema, and
16+
backed by [ArangoDB](https://www.arangodb.com/).
17+
```bash
18+
$ ./build.sh
19+
```

0 commit comments

Comments
 (0)