What?
Okay then, this is related to my previous article about Rakkit. So I'll advise you to go take a look around ๐.
So, here I will show you a more concrete example of what you can do using Rakkit to create a GraphQL API with a user management system.
But first: the installation of Rakkit ๐พ
So there are few dependencies that we must install to continue:
Here, I would use
apollo-server
but it's also possible to installapollo-server-koa
if you use Rakkit for REST and GraphQL which allows you to link contexts.
Just run this command to install the required dependencies:
npm i rakkit graphql @types/graphql apollo-server reflect-metadata
reflect-metadata allows us to use the decorators with TypeScript
Okay cool, now we just need to configure TypeScript to enable the decorators by creating a tsconfig.json file at the root of the project, containing this:
{
"compileOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "commonjs",
"target": "es2016",
"noImplicitAny": false,
"sourceMap": true,
"outDir": "build",
"declaration": true,
"importHelpers": true,
"forceConsistentCasingInFileNames": true,
"lib": [
"es2016",
"esnext.asyncitable"
],
"moduleResolution": "node"
}
}
./tsconfig.json
The definitions of types ๐ป
Okay then let's start by creating our User
class, which we'll have to decorate with @ObjectType()
:
import { ObjectType, Field } from "rakkit";
import * as Crypto from "crypto";
@ObjectType()
export class User {
@Field()
username: string;
@Field()
email: string;
@Field()
id: string;
// Just to show a computed property:
@Field(type => String)
get flatInfos(): string {
return [this.name, this.email, this.id].join(":");
}
constructor(username: string, email: string) {
this.username = username;
this.email = email;
this.id = Crypto.randomBytes(16).toString("hex");
}
}
./types/User.ts
You need a small "database" ๐
So we're going to have to play with some users in order to test our app, so I'm just going to create a list of user instances to make it clearer:
You can use a real database with an ORM like TypeORM for your projects
import { User } from "../types/User";
export const users = [
new User("JohnDoe", "john@doe.com"),
new User("JaneDoe", "jane@doe.com"),
new User("Ben", "ben@doe.com")
];
./db/users.ts
Resolver (Query, Mutation, Subscription) ๐
It is in the following class that we will define our query/mutation/subscription. It will contain a simple CRUD and a subscription to be notified when a user is registered:
import {
Resolve,
Query,
Mutation,
Subscription,
IContext,
Arg
} from "rakkit";
import { User } from "../types/User";
import { users } from "../db/users";
@Resolver()
export class UserResolver {
@Query(returns => [User])
getAllUsers() { {
return users;
}
@Query({ nullable: true })
getOneUserByName(@Arg("name") name: string): User {
return users.find((user) => user.name ==== name);
}
@Mutation()
addUser(
// Defining the mutation arguments
@Arg("name") name: string,
@Arg("email") email: string,
context: IContext
): User {
const user = new User(name, email);
users.push(user);
// Publish the event for subscriptions with the created user
context.gql.pubSub.publish("USER_ADDED", user);
return user;
}
@Subscription({ topics: "USER_ADDED" })
userAddedNotif(createdUser: User): User {
// Send the created user to the client
return createdUser;
}
}
./resolvers/UserResolver.ts
The point of entry ๐ช
Now we need to have an entry point for our application:
// It allows us to use decorators:
import "reflect-metadata";
import { Rakkit } from "rakkit";
import { ApolloServer } from "apollo-server";
async function bootstrap() {
await Rakkit.start({
gql: {
// You give an array of glob string:
resolvers: [`${__dirname}/resolvers/*Resolver.ts`]
}
});
// Retrieve the GraphQL compiled schema:
const schema = Rakkit.MetadataStorage.Gql.Schema;
const server = new ApolloServer({
schema
});
server.listen();
}
bootstrap();
./bootstrap.ts
Done, so let's start and test it ! ๐
To start it you must install ts-node
globally to run directly your TypeScript app:
npm i -g ts-node
Then just run this:
ts-node relative-path-to/bootstrap.ts
And just go to http://localhost:4000 with your favorite browser to make some GraphQL queries! ๐ฅ
getOneUserByName - Get a specific user by name:
userAddedNotif - Listen to the user creation event:
Top comments (3)
Oh wow, this looks just like an exact copy of
@nestjs/graphql
just without the big community to back it up.. lolYes the GraphQL package looks like type-graphql (used by nest) but there is several differences that are mentioned in the docs ๐
For the community, every projects start from zero, we are building it ๐
Well, IMO reinventing the wheel is never good :)
And especially in this case it makes absolutely no sense at all.
What would you rather use? A new framework which reinvents everything (not even better), or a battle production tested framework with several community backed packages?