Have you ever wanted to setup a TypeORM, MySQL with Apollo graphQL server? If so, you've come to the right place! In this blog post, we'll be walking you through the steps necessary to set up a TypeORM, MySQL with Apollo graphQL server. We'll cover everything from setting up the environment to creating the schema for your database. By the end of this post, you'll be ready to start building powerful GraphQL applications with TypeORM and MySQL. So, let's get started!
TypeORM
What is TypeORM? TypeORM is an ORM that can run in NodeJS, Browser, React Native and any platform that you can run javascript. It can be used with TypeScript and JavaScript. The aim of TypeORM is to provide a way to manage your data as objects. TypeORM is great because what would have gone out of hand, is kept under control.
You will notice right away, the amount code reduction you will get from this library.
It provides tools that enable the development of any database-related application - from small projects with a few tables to large-scale enterprise applications with multiple databases. TypeORM can be configured for use with a number of different databases, including; MySQL, PostgreSQL, SQL lite, MongoDB amongst others.
To get started, we need to start a NodeJS projects, for this you need to ensure that you have NodeJS installed on your computer. Open up a terminal and run
$ node -v
This will return the current version of NodeJS you have installed, if you don't get back that version then you can head to NodeJS website to download the latest stable version. Next we need to spin up a new NodeJS project.
$ npm init --y
After you have the project initialized, we can now go ahead and install TypeORM and reflect-metadata shim with the following command
$ npm install typeorm reflect-metadata
Let's install node typedefs since TypeORM works excellently with Typescript.
$ npm install -D @types/node
You will need to install a database driver, for this project our database of choice will be MySQL, thus we need to install that. What I do is, I already have Xampp installed on my computer, if you would rather have Xampp then you can head to Apache Friends to download and install Xampp. Otherwise you can install the Javascript driver for MySQL.
$ npm install mysql
If you have MySQL installed and setup. You can create a user for this purpose. You can also create your database. Start up your mysql server.
The next step would be to ensure that your tsconfig.json
file has the following in the compilerOptions
then we setup the TypeORM project.
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true
}
}
Now we have our tsconfig
file with the right configurations, we need to setup a TypeORM project using the following command;
npx typeorm init --database mysql
This the quickest way to get started with TypeORM, to use CLI commands to generate a starter project. Note that this will only work if you are using TypeORM in a NodeJS application.
MyProject
├── src
│ ├── entity
│ │ └── User.ts
│ ├── migration
│ ├── data-source.ts
│ └── index.ts
├── .gitignore
├── package.json
├── README.md
└── tsconfig.json
Open up data-source.ts
we will edit this file, we need to enter our database username, password and the database we are going to work with.
// data-source.ts
import "reflect-metadata";
import { DataSource } from "typeorm";
import { User } from "./entity/User";
const dataSource = new DataSource({
type: "mysql",
host: "localhost",
port: 3306,
username: "root", // replace with your username
password: "", // replace with your password
database: "demo-library", // replace with your database
synchronize: true,
logging: false,
entities: [User],
migrations: [],
subscribers: [],
})
export const AppDataSource = dataSource.initialize()
The next thing to do is to install the dependencies that the will power the code generated by setting up the TypeORM project. For that we can just run
$ npm i
TypeORM will generate an entity for us by default, that entity is imported into the data-source.ts
file we will be using only that entity in this example as we are trying to keep things simple and straight forward. We are done with TypeORM for now, let's move into integrating Apollo Server into the codebase.
Apollo Server
Apollo Server is an open source and spec-compliant GraphQL server that works with all GraphQL clients, including Apollo Client. It is the optimal way to create a production-ready and self-describing GraphQL API that can leverage data from any source. We need to install apollo server and graphQL
$ npm install @apollo/server graphql
We have to edit our tsconfig.json
file again so it is compliant with Apollo Server for Typescript, add the following to the compilerOptions
.
{
"compilerOptions": {
"rootDirs": ["src"],
"outDir": "dist",
"lib": ["es2020"],
"target": "es2020",
"module": "esnext",
"moduleResolution": "node",
"esModuleInterop": true,
"types": ["node"]
}
}
over all your tsconfig
file should have the following content;
// ts.config
{
"compilerOptions": {
"lib": [
"es5",
"es6",
"es2020"
],
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"sourceMap": true,
"rootDirs": ["./src"],
"outDir": "dist",
"target": "ESNext",
"module": "CommonJS",
"moduleResolution": "node",
"esModuleInterop": true,
"types": ["node"]
},
"exclude": ["node_modules"],
"include": ["./src/**/*"]
}
Let's define a schema for the user entity generated by default. This is basic graphQL so I will assume that you already know how graphQL schemas work, I won't go into detail about that
type User {
id: Int
firstName: String
lastName: String
age: Int
}
type Query {
users: [User]
user(id: Int): User
}
Let's write a resolver for this query using TypeORM, we will import the User
entity and our appDataSource
into our resolver file.
// resolver.ts
import { User } from "./entity/User";
import { AppDataSource } from "data-source.ts"
export const UserQueries = {
users: async function(_, __) {
const Users = await AppDataSource.getRepository(User);
return await Users.find();
},
user: async function (_, { id }: Partial<Pick<User, 'id'>>) {
const Users = await AppDataSource.getRepository(User);
const user = await Users.findOneBy({ id });
if (user) {
return user;
}
throw Error('No user with that ID');
}
}
We've defined our schema and resolver. Now we need to provide this information to Apollo Server when we initialize it.
// index.ts
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
import { readFileSync } from 'fs'
import path from 'path'
import { UserQueries } from './resolver';
const resolvers = {
Query: {
...UserQueries
}
}
const typeDefs = readFileSync(path.resolve('./schema.graphql')).toString('utf-8');
const server = new ApolloServer({
typeDefs,
resolvers,
});
startStandaloneServer(server, {
listen: { port: 4000 }
}).then(({ url}) => console.log(`🚀 Server ready at: ${url}`));
There you go, our graphQL server all setup with TypeORM, MySQL and Apollo Server.