GraphQL needs both Type
and Resolver
to handle the request and response.
GraphQL Route
@GraphQL()
export class VersionGraphQL {}
Create
GraphQL can be created in typescript by using GraphQLSchema
interface.
Both typeDefs
and Query
are required.
export const VersionType: GraphQLSchema = {
typeDefs: `
type Version {
version: Int
name: String
createdAt: Int
updatedAt: Int
}`,
Query: `
versions: [Version]
version(name:String!):[Version]
`,
};
and use it as argument of @GraphQL
like @GraphQL(VersionType)
Create GraphQL by file .graphql
in graphql directory
With this way all files in the ./graphql
directory will be using as type definition.
all files must be end with .graphql
extension.
type Version {
version: Int
name: String
createdAt: Int
updatedAt: Int
}
type Query {
versions: [Version]
version(name: String!): [Version]
}
Resolver
GraphQL Resolver is the implementation layer of type Query which is defined in the GraphQL file or object.
type VersionFilter = {
name: string;
};
@GraphQL()
export class VersionGraphQL {
private _versions = [
{
version: 1,
name: "version1",
createdAt: 223123,
updatedAt: 55343,
},
{
version: 2,
name: "version2",
createdAt: 223123,
updatedAt: 55343,
},
];
constructor() {}
@Resolver()
async version(@Params() filter: VersionFilter, @Param("name") name: string) {
return this._versions.filter((x) => x.name === filter.name); // name
}
@Resolver()
async versions() {
return this._versions;
}
}
Secure an Endpoint
You can secure graphql api by using the @Guard
.
@GraphQL()
@Guard({ roles: ["admin"] })
export class VersionGraphQL {
constructor(private readonly _service: TodoService) {}
@Resolver()
@Guard({ roles: ["admin"], permissions: ["find-all"] })
async versions() {
return this._versions;
}
@Resolver()
async version(@Params() filter: VersionFilter, @Param("name") name: string) {
return this._versions.filter((x) => x.name === filter.name); // name
}
}
Register GraphQL
@Module({
graphqls: [VersionGraphQL],
})
export class AppModule {}
Supported Decorators
Decorator | Description | Note |
---|---|---|
@GraphQL | Declare a class as GraphQL Controller | has one argument for GraphQL Type |
@Resolver | Declare a GraphQL Resolver for a Query function. | |
@Guard | Declare a GuardContext for protecting the resource access |
Settings
GraphQL Server is a sub server of Heron.
const main = async () => {
const app = await HeronJS.create({ module: AppModule });
await app.listen({
port: 3000,
options: {
cors: {
origin: "*",
preflightContinue: false,
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
},
globalError: GlobalApiErrorInterceptor,
},
subServer: {
graphql: {
prefix: "/gpl",
gqlDir: "./graphql",
cors: {},
formatError: (error) => {},
plugins: [],
validationRules: [],
},
},
});
};
Argument | Description | Note |
---|---|---|
prefix | create global prefix for graphql | |
gqlDir | graphql scalar type file dir | default is ./graphql |
cors | apply cors for graphql apis | will use http cors as default if this value not provided |
formatError | global error format | this will change the format of error before response back to client |
plugins | express-graphql plugin | |
validationRules | express-graphql validation rules |