-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5817baa
commit b936d16
Showing
22 changed files
with
30,071 additions
and
4,083 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"name": "apollo-server-starter", | ||
"version": "0.0.1", | ||
"description": "", | ||
"main": "./dist/index.js", | ||
"license": "MIT", | ||
"scripts": { | ||
"build": "tsc", | ||
"dev": "tsnd --respawn --transpile-only src/index.ts", | ||
"watch": "tsc --watch", | ||
"check": "tsc --noEmit" | ||
}, | ||
"dependencies": { | ||
"apollo-graphql": "^0.9.5", | ||
"apollo-server": "^3.6.4", | ||
"apollo-server-core": "^3.6.4", | ||
"chalk": "4.0.0", | ||
"class-validator": "^0.13.2", | ||
"graphql": "^15.3.0", | ||
"graphql-subscriptions": "^2.0.0", | ||
"nexus": "^1.3.0", | ||
"nexus-plugin-prisma": "^0.35.0", | ||
"reflect-metadata": "^0.1.13", | ||
"type-graphql": "^1.1.1" | ||
}, | ||
"resolutions": { | ||
"graphql": "^15.3.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import chalk from 'chalk'; | ||
import { ApolloServer, gql } from 'apollo-server'; | ||
import { | ||
ApolloServerPluginLandingPageGraphQLPlayground, | ||
ApolloServerPluginLandingPageDisabled, | ||
} from 'apollo-server-core'; | ||
|
||
export const typeDefs = gql` | ||
# This "Book" type defines the queryable fields for every book in our data source. | ||
type Book { | ||
title: String | ||
author: String | ||
} | ||
# The "Query" type is special: it lists all of the available queries that | ||
# clients can execute, along with the return type for each. In this | ||
# case, the "books" query returns an array of zero or more Books (defined above). | ||
type Query { | ||
books: [Book] | ||
} | ||
`; | ||
|
||
const books = [ | ||
{ | ||
title: 'The Awakening', | ||
author: 'Kate Chopin', | ||
}, | ||
{ | ||
title: 'City of Glass', | ||
author: 'Paul Auster', | ||
}, | ||
]; | ||
|
||
export const resolvers = { | ||
Query: { | ||
books: () => books, | ||
}, | ||
}; | ||
|
||
export async function bootstrap() { | ||
const server = new ApolloServer({ | ||
typeDefs, | ||
resolvers, | ||
plugins: [ | ||
process.env.NODE_ENV === 'production' | ||
? ApolloServerPluginLandingPageDisabled() | ||
: ApolloServerPluginLandingPageGraphQLPlayground(), | ||
], | ||
}); | ||
|
||
server.listen().then(({ url }) => { | ||
console.log(`🚀 Server ready at ${chalk.green(url)}`); | ||
}); | ||
} |
161 changes: 161 additions & 0 deletions
161
packages/apollo-server-starter/src/impl/type-graphql.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
import 'reflect-metadata'; | ||
import chalk from 'chalk'; | ||
import { ApolloServer } from 'apollo-server'; | ||
import { | ||
ApolloServerPluginLandingPageGraphQLPlayground, | ||
ApolloServerPluginLandingPageDisabled, | ||
} from 'apollo-server-core'; | ||
|
||
import { | ||
Field, | ||
ObjectType, | ||
Int, | ||
Float, | ||
Arg, | ||
FieldResolver, | ||
Mutation, | ||
Query, | ||
Resolver, | ||
ResolverInterface, | ||
Root, | ||
InputType, | ||
buildSchema, | ||
} from 'type-graphql'; | ||
import path from 'path'; | ||
|
||
@ObjectType({ description: 'Object representing cooking recipe' }) | ||
export class Recipe { | ||
@Field() | ||
title!: string; | ||
|
||
@Field((type) => String, { | ||
nullable: true, | ||
deprecationReason: 'Use `description` field instead', | ||
}) | ||
get specification(): string | undefined { | ||
return this.description; | ||
} | ||
|
||
@Field({ | ||
nullable: true, | ||
description: 'The recipe description with preparation info', | ||
}) | ||
description?: string; | ||
|
||
@Field((type) => [Int]) | ||
ratings!: number[]; | ||
|
||
@Field() | ||
creationDate!: Date; | ||
|
||
@Field((type) => Int) | ||
ratingsCount!: number; | ||
|
||
@Field((type) => Float, { nullable: true }) | ||
get averageRating(): number | null { | ||
const ratingsCount = this.ratings.length; | ||
if (ratingsCount === 0) { | ||
return null; | ||
} | ||
const ratingsSum = this.ratings.reduce((a, b) => a + b, 0); | ||
return ratingsSum / ratingsCount; | ||
} | ||
} | ||
|
||
@InputType() | ||
export class RecipeInput implements Partial<Recipe> { | ||
@Field() | ||
title!: string; | ||
|
||
@Field({ nullable: true }) | ||
description?: string; | ||
} | ||
|
||
export function createRecipeSamples() { | ||
return [ | ||
createRecipe({ | ||
description: 'Desc 1', | ||
title: 'Recipe 1', | ||
ratings: [0, 3, 1], | ||
creationDate: new Date('2018-04-11'), | ||
}), | ||
createRecipe({ | ||
description: 'Desc 2', | ||
title: 'Recipe 2', | ||
ratings: [4, 2, 3, 1], | ||
creationDate: new Date('2018-04-15'), | ||
}), | ||
createRecipe({ | ||
description: 'Desc 3', | ||
title: 'Recipe 3', | ||
ratings: [5, 4], | ||
creationDate: new Date(), | ||
}), | ||
]; | ||
} | ||
|
||
function createRecipe(recipeData: Partial<Recipe>) { | ||
return Object.assign(new Recipe(), recipeData); | ||
} | ||
|
||
@Resolver((of) => Recipe) | ||
export class RecipeResolver implements ResolverInterface<Recipe> { | ||
private readonly items: Recipe[] = createRecipeSamples(); | ||
|
||
@Query((returns) => Recipe, { nullable: true }) | ||
async recipe(@Arg('title') title: string): Promise<Recipe | undefined> { | ||
return await this.items.find((recipe) => recipe.title === title); | ||
} | ||
|
||
@Query((returns) => [Recipe], { | ||
description: 'Get all the recipes from around the world ', | ||
}) | ||
async recipes(): Promise<Recipe[]> { | ||
return await this.items; | ||
} | ||
|
||
@Mutation((returns) => Recipe) | ||
async addRecipe(@Arg('recipe') recipeInput: RecipeInput): Promise<Recipe> { | ||
const recipe = Object.assign(new Recipe(), { | ||
description: recipeInput.description, | ||
title: recipeInput.title, | ||
ratings: [], | ||
creationDate: new Date(), | ||
}); | ||
await this.items.push(recipe); | ||
return recipe; | ||
} | ||
|
||
@FieldResolver() | ||
ratingsCount( | ||
@Root() recipe: Recipe, | ||
@Arg('minRate', (type) => Int, { defaultValue: 0.0 }) minRate: number | ||
): number { | ||
return recipe.ratings.filter((rating) => rating >= minRate).length; | ||
} | ||
} | ||
|
||
export async function bootstrap() { | ||
// build TypeGraphQL executable schema | ||
const schema = await buildSchema({ | ||
resolvers: [RecipeResolver], | ||
// automatically create `schema.gql` file with schema definition in current folder | ||
emitSchemaFile: path.resolve(__dirname, '../type-graphql.schema.gql'), | ||
}); | ||
|
||
// Create GraphQL server | ||
const server = new ApolloServer({ | ||
schema, | ||
plugins: [ | ||
process.env.NODE_ENV === 'production' | ||
? ApolloServerPluginLandingPageDisabled() | ||
: ApolloServerPluginLandingPageGraphQLPlayground(), | ||
], | ||
}); | ||
|
||
// Start the server | ||
const { url } = await server.listen(4001); | ||
console.log( | ||
`Server is running, GraphQL Playground available at ${chalk.green(url)}` | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { bootstrap as PlainBootstrap } from './impl/plain'; | ||
import { bootstrap as TypeGraphQLBootstrap } from './impl/type-graphql'; | ||
|
||
PlainBootstrap(); | ||
TypeGraphQLBootstrap(); |
38 changes: 38 additions & 0 deletions
38
packages/apollo-server-starter/src/type-graphql.schema.gql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# ----------------------------------------------- | ||
# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! | ||
# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! | ||
# ----------------------------------------------- | ||
|
||
""" | ||
The javascript `Date` as string. Type represents date and time as the ISO Date string. | ||
""" | ||
scalar DateTime | ||
|
||
type Mutation { | ||
addRecipe(recipe: RecipeInput!): Recipe! | ||
} | ||
|
||
type Query { | ||
recipe(title: String!): Recipe | ||
|
||
"""Get all the recipes from around the world """ | ||
recipes: [Recipe!]! | ||
} | ||
|
||
"""Object representing cooking recipe""" | ||
type Recipe { | ||
averageRating: Float | ||
creationDate: DateTime! | ||
|
||
"""The recipe description with preparation info""" | ||
description: String | ||
ratings: [Int!]! | ||
ratingsCount(minRate: Int = 0): Int! | ||
specification: String @deprecated(reason: "Use `description` field instead") | ||
title: String! | ||
} | ||
|
||
input RecipeInput { | ||
description: String | ||
title: String! | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"extends": "../../tsconfig.base.json", | ||
"compilerOptions": { | ||
"target": "ES2018", | ||
"module": "commonjs", | ||
"lib": [ | ||
"esnext" | ||
], | ||
"rootDir": "src", | ||
"outDir": "dist", | ||
"esModuleInterop": true, | ||
"skipLibCheck": true, | ||
"declaration": true, | ||
"emitDecoratorMetadata": true, | ||
"experimentalDecorators": true | ||
}, | ||
"include": [ | ||
"src" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Binary file not shown.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.