Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a97df72
fixed typings
Oct 20, 2017
4dc942b
created generic description method & field decorator can set description
Oct 20, 2017
c861400
implemented NonNull as Field option
Oct 20, 2017
f4e62be
implemente4d description as schema option
Oct 20, 2017
02d5cd9
implemented description for Query & Mutation options
Oct 20, 2017
1137265
created description for List option
Oct 20, 2017
318734c
made option optional
Oct 20, 2017
30ae888
completed implementing description as part of other decoration option
Oct 20, 2017
fe0ee68
refactored setDescriptionMetadata, simplified
Oct 20, 2017
7fdbbe8
created new sample
playerx Oct 21, 2017
c40c450
removed unused decorators
playerx Oct 21, 2017
2a59e06
formatted
playerx Oct 21, 2017
30bf6fb
created DefaultOption
playerx Oct 21, 2017
109932e
created new options for field decorator & created tests
playerx Oct 21, 2017
e238e8d
updated sample
playerx Oct 21, 2017
b0ab52d
added:
playerx Oct 21, 2017
c664e20
updated documentation & samples
playerx Oct 21, 2017
81984d7
created initial subscription support
playerx Oct 22, 2017
7cafb4a
* removed debug info
playerx Oct 22, 2017
8d5e055
updated demo project, crated subscription sample with documentation
playerx Oct 22, 2017
d5101f8
fixed undefined parameter
playerx Oct 22, 2017
354ed22
updated types for graphql up to 0.11.5
playerx Oct 22, 2017
9e2bcc0
updated example project, created paging & orderby sample
playerx Oct 22, 2017
fe87cdf
* refactoring
playerx Oct 22, 2017
c52357b
updated documentation
playerx Oct 22, 2017
85a57d7
added printSchema endpoint
playerx Oct 22, 2017
2d8e76d
added esnext lib
playerx Oct 22, 2017
6adb24f
fixed examples
playerx Oct 22, 2017
eb59629
removed commented code
playerx Oct 24, 2017
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
72 changes: 28 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,32 +44,26 @@ export class RootSchema {

Example usage of @Ctx and @Root.
```typescript
import { NonNull, ObjectType, Ctx, List, Field, Description, Root } from 'graphql-decorator';
import { ObjectType, Ctx, Field, Root } from 'graphql-decorator';
import { GraphQLID, GraphQLString, GraphQLList } from 'graphql';
import * as AnswerTypes from 'graphql/answer/types/index';

@ObjectType()
@Description('An user')
@ObjectType({description: 'An user'})
export class UserType {

@NonNull()
@Field({type: GraphQLID})
@Field({type: GraphQLID, nonNull: true})
id: number;

@NonNull()
@Field({type: GraphQLString})
@Field({type: GraphQLString, })
name: string;

@NonNull()
@Field({type: GraphQLString})
@Field({type: GraphQLString, nonNull: true})
avatarUrl: string;

@NonNull()
@Field({type: GraphQLString})
@Field({type: GraphQLString, nonNull: true})
email: string;

@List()
@Field({type: AnswerTypes.AnswerType})
@Field({type: AnswerTypes.AnswerType, isList: true})
answers(@Ctx() context: any, @Root() root: any) {
// Get answers using ctx and root.
}
Expand All @@ -79,30 +73,28 @@ export class UserType {

Use of @Pagination with @OrderBy
```typescript
import { ObjectType, Arg, Pagination, Ctx, List, Field, Description } from 'graphql-decorator';
import { ObjectType, Arg, Ctx, List, Field } from 'graphql-decorator';

@ObjectType()
@Description("Get all users query.")
@ObjectType({description: 'Get all users query.'})
export class UsersQuery {

@Pagination()
@Field({type: UserType})
users(@Ctx() context: any, @Arg({name: "offset"}) offset: number, @Arg({name: "limit"}) limit: number, @OrderBy() orderBy: orderByItem[]) {
@Field({type: UserType, pagination: true})
users(
@Ctx() context: any,
@Arg({name: "offset"}) offset: number,
@Arg({name: "limit"}) limit: number,
@OrderBy() orderBy: orderByItem[]
) {
// Get users
}

@ObjectType()
@Description("An user.")
@ObjectType({description: 'An user.'})
export class UserType {

@NonNull()
@Description("User id")
@Field({type: GraphQLID})
@Field({type: GraphQLID, description: 'User id', nonNull: true})
id: number;

@NonNull()
@Description("User name")
@Field({type: GraphQLString})
@Field({type: GraphQLString, description: 'User name', nonNull: true})
name: string;
}

Expand Down Expand Up @@ -139,20 +131,16 @@ Use of @EnumType and @Value
```typescript
import { EnumType, Description, Value } from 'graphql-schema-decorator';

@EnumType()
@Description('An user role. Either ADMIN or DEFAULT')
@EnumType({description: 'An user role. Either ADMIN or DEFAULT'})
export class UserRoleType {

@Value(0)
@Description("Admin role")
@Value(0, {description: 'Admin role'})
ADMIN: string;

@Value("value")
@Description("Default role")
@Value('value', {description: 'Default role'})
DEFAULT: string;

@Value()
@Description("God role")
GOD: string;

}
Expand All @@ -162,12 +150,10 @@ And you can use the just declared enum like this.
import { ObjectType, Arg, Pagination, Field, Description } from 'graphql-schema-decorator';
import * as UserTypes from 'graphql-schema/user/type';

@ObjectType()
@Description("Get all users query.")
@ObjectType({description: 'Get all users query.'})
export class UsersQuery {

@Pagination()
@Field({type: UserTypes.UserType})
@Field({type: UserTypes.UserType, pagination: true})
users(@Arg({name: "role", type: UserTypes.UserRoleType }) role: any) {
// The role value will either be 0, "value" or GOD.
// Get users by role.
Expand All @@ -184,8 +170,7 @@ import * as BannerTypes from 'graphql-schema/banner/type/banner.type';
import { BannerRepository, BannerLocalDataSource } from 'data/source/banner';
import { ModuleRepository } from 'data/source/module';

@ObjectType()
@Description("Get a list of banners.")
@ObjectType({description: 'Get a list of banners.'})
@UseContainer(Container)
@Service()
export class BannersQuery {
Expand All @@ -194,8 +179,7 @@ export class BannersQuery {
private readonly bannerRepository: BannerRepository
) { }

@List()
@Field({type: BannerTypes.BannerType})
@Field({type: BannerTypes.BannerType, isList: true})
banners() {
return this.bannerRepository.getBanners();
}
Expand Down Expand Up @@ -343,13 +327,13 @@ You can use `@NonNull` and `@List` decorator. For example:
```ts
@ObjectType()
class User {
@NonNull() @Field({type: graphql.GraphQLID})
@Field({type: graphql.GraphQLID, nonNull: true})
id: string;
}

@ObjectType()
class Query {
@List() @Field({type: User}) getAllUsers(): Promise<User[]> {
@Field({type: User, isList: true}) getAllUsers(): Promise<User[]> {
/* implementation for fetch all users */
}
}
Expand Down
13 changes: 13 additions & 0 deletions examples/apollo-server/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Editor configuration, see http://editorconfig.org
root = true

[*]
charset = utf-8
indent_style = tab
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
max_line_length = off
trim_trailing_whitespace = false
44 changes: 44 additions & 0 deletions examples/apollo-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Simple CRUD example

## Install

```sh
npm i
```

### Run

```sh
npm start
```

And open http://localhost:3000/ in your browser.


##### Subscribe
```gql
subscription {
userAdded {
id
name
email
}
}
```


##### Push
```gql
mutation {
addUser(input: {name: "Ezeki", email: "ez@jok.io"}) {
id
}
}
```


##### View Generated Schema
```
http://localhost:3000/schema
```

10 changes: 10 additions & 0 deletions examples/apollo-server/nodemon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"watch": [
"src"
],
"ext": "ts",
"ignore": [
"src/**/*.spec.ts"
],
"exec": "ts-node ./src/server.ts"
}
35 changes: 35 additions & 0 deletions examples/apollo-server/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "simple-crud",
"version": "1.0.0",
"description": "CRUD example of graphql-decortor",
"main": "index.js",
"scripts": {
"start": "nodemon"
},
"dependencies": {
"@types/hapi": "^16.1.10",
"apollo-server-express": "^1.1.7",
"apollo-server-hapi": "^1.1.7",
"cors": "^2.8.4",
"express": "^4.14.0",
"express-graphql": "^0.5.3",
"graphql": "0.11.7",
"graphql-decorator": "file:../../",
"graphql-subscriptions": "^0.5.4",
"hapi": "^16.6.2",
"nodemon": "^1.12.1",
"subscriptions-transport-ws": "^0.9.1",
"typescript": "2.5.3"
},
"peerDependencies": {
"graphql": "0.11.7"
},
"keywords": [],
"author": "Quramy",
"license": "ISC",
"devDependencies": {
"@types/express": "^4.0.23-alpha",
"@types/node": "7.0.5",
"@types/graphql": "^0.11.5"
}
}
3 changes: 3 additions & 0 deletions examples/apollo-server/src/common/pubsub.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { PubSub } from 'graphql-subscriptions';

export const pubsub = new PubSub();
49 changes: 49 additions & 0 deletions examples/apollo-server/src/common/server.express.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as express from 'express';
import * as bodyParser from 'body-parser';
import { createServer, Server } from 'http';
import { graphqlExpress, graphiqlExpress } from 'apollo-server-express';
import { SubscriptionServer } from 'subscriptions-transport-ws';
import { execute, subscribe, printSchema } from 'graphql';
import * as cors from 'cors';


export default function startGraphQLServer(
schema,
domain = 'localhost',
port = process.env.PORT,
path = '/graphql',
) {
const PORT = port;
// const myGraphQLSchema: any = schema; // ... define or import your schema here!

const app: express.Express = express();

// bodyParser is needed just for POST.
app.use('/', cors(), bodyParser.json(), graphqlExpress({ schema }));

app.get('/debug', graphiqlExpress({
endpointURL: '/',
editorTheme: '',
subscriptionsEndpoint: `ws://${domain}:${PORT}/subscriptions`,
})); // if you want GraphiQL enabled

app.get('/schema', (req, res) => {
const schemaString = printSchema(schema);

res.write(schemaString);
res.end();
});

const ws: Server = createServer(app);

ws.listen(PORT, () => {
console.log(`GraphQL Server is now running on http://${domain}:${PORT}`);

// set up the WebSocket for handling GraphQL subscriptions
const sub: SubscriptionServer = new SubscriptionServer({
execute,
subscribe,
schema,
}, { server: ws, path: '/subscriptions' });
});
}
74 changes: 74 additions & 0 deletions examples/apollo-server/src/common/server.hapi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import * as hapi from 'hapi';
import { graphqlHapi, graphiqlHapi, HapiPluginOptions, HapiGraphiQLPluginOptions } from 'apollo-server-hapi';
import { SubscriptionServer } from 'subscriptions-transport-ws';
import { execute, subscribe, printSchema } from 'graphql';


export default function serverHapi(
schema,
domain = 'localhost',
port = process.env.PORT || 3000,
path = '/graphql',
) {
const server = new hapi.Server({ debug: false });

const HOST = domain;
const PORT = port;
const SUBSCRIPTIONS_PATH = '/subscriptions';

const graphqlOptions: HapiPluginOptions = {
path,
graphqlOptions: {
schema,
},
route: {
cors: true,
},
};

const graphiqlOptions: HapiGraphiQLPluginOptions = {
path: '/',
graphiqlOptions: {
endpointURL: path,
subscriptionsEndpoint: `ws://${HOST}:${PORT}${SUBSCRIPTIONS_PATH}`,
},
};

server.connection({
host: HOST,
port: PORT,
});

server.register({
register: graphqlHapi,
options: graphqlOptions,
});

server.register({
register: graphiqlHapi,
options: graphiqlOptions,
});

server.route({
method: 'GET',
path: '/schema',
handler: (request, reply) =>
reply.response(printSchema(schema)).type('text/plain'),
});



server.start((err) => {
if (err) {
throw err;
}

const sub: SubscriptionServer = new SubscriptionServer({
execute,
subscribe,
schema,
}, { server: server.listener, path: SUBSCRIPTIONS_PATH });

console.log(`Server running at: ${server.info.uri}`);
});
}
Loading