In this guide i’ll walk you through how to set up node s server frote point of view of a beginner who’s being tinkering around for the last 6 months and help you avoid the common issues i ran into in the process
I;ll assume you know the basic in javascript,typescript and graphql
But i’ll try and organise the github commits from the most basic
the typescript setup might be little cumbersome so i’d advise to clone the repo first before beginning this tutorial
Navigate to the initial commit and download or clone repo if you have git installed
You’ll also need to install and setup mongodb on your device or use mongo atlas , am not a fan of mongodb compass because of its lack of dark mode so i use the vscode extension MySQL database viewer:
https://marketplace.visualstudio.com/items?itemName=cweijan.vsc
Install and connect to sql and nosql databases
You might also vscode extensions for
Graphql and typescript
Run “npm install” in it’s root directory
Then npm run watch or yarn watch to watch for ts changes
Open another terminal to run npm start or yarn start
import express from "express";
import cors from 'cors'
import { ApolloServer } from 'apollo-server-express';
import { gql } from 'apollo-server-express';
const PORT=4000;
const typeDefs =
gql`
type Query {
defaultPost:String
}
`;
const resolvers = {
Query: {
defaultPost: () => "eat your vegetables",
},
};
const startServer=async()=>
{
const app = express();
const allowedOrigins = [
'http://localhost:3000',
'http://localhost:3001',
'https://studio.apollographql.com'
];
const corsOptions = {
credentials: true,
origin: function(origin, callback){
if(!origin) return callback(null, true);
if(allowedOrigins.indexOf(origin) === -1){
var msg = 'The CORS policy for this site does not ' +
'allow access from the specified Origin.';
return callback(new Error(msg), false);
}
return callback(null, true);
}
}
app.use(cors(corsOptions))
//rest routes
app.get("/", (req, res) => {
res.json({
data: "API is working...",
});
});
const server = new ApolloServer({
typeDefs,
resolvers,
});
await server.start();
server.applyMiddleware({ app });
app.listen(PORT, () => {
console.log(` Server is running at http://localhost:${PORT}`);
});
}
startServer().catch(e=>console.log("error strting server======== ",e))
our server is now ready navigate to
http://localhost:4000/graphql
to preview our server in apollo's playground and run our first query
on the right hand side we have all the operatons which you can navigate to by clicking the the pluss button and adding field then run it and the response is displayed in the left hand side.
now we'll add mongodb into the project:
var uri = "mongodb://localhost:27017/testmongo";
//@ts-ignore
mongoose.connect(uri, { useUnifiedTopology: true, useNewUrlParser: true })
.then(()=>console.log("connected to newmango db"))
this will auto-create a newmango collection for us
now we'll create a new directory models/TestModel.ts
then add this code to create a new mongo db model
import mongoose from "mongoose";
const Schema = mongoose.Schema;
const TestSchema = new Schema({
title: {
type: String,
required: true
},
desc: {
type: String,
required: true
},
},
//add this for auto createdAt and updatedat fields
{timestamps:true}
);
export const TestModel= mongoose.model("Test", TestSchema);
then we'll also create resolver/TestResolver.ts and typeDefs/typeDef.ts
import { TestModel } from "./../model/TestModel";
export const resolvers = {
Query: {
defaultPost: () => "eat your vegetables",
getItems: async () => {
const chats = await TestModel.find({});
console.log("holt output ======", chats);
return chats;
},
},
Mutation: {
//shape of params (parent,args, context, info)
addItem: async (parent, { title, desc }, context, info) => {
let item={}
let error={}
try{
const newItem = await new TestModel({
title,
desc,
});
item=await newItem.save()
console.log("item ==== ",item)
}catch(e){
console.log("addTest error response =====", e.message);
error=e
}
return {
item:item,
error:{
//@ts-ignore
message:error.message
}
};
},
},
};
import { gql } from 'apollo-server-express';
export const typeDefs =
gql`type Item{
title:String,
desc:String
}
type Error{
message:String
}
type ItemResponse{
item:Item
error:Error
}
type Query {
defaultPost:String,
getItems:[Item]
},
type Mutation{
addItem(title:String,desc:String):ItemResponse
}
`;
add the respective code and import it in the index.ts
import express from "express";
import cors from 'cors'
import { ApolloServer } from 'apollo-server-express';
import mongoose from 'mongoose';
import { resolvers } from './resolvers/TestResolver';
import { typeDefs } from './typeDefs/typedefs';
const PORT=4000;
const startServer=async()=>
{
const app = express();
const allowedOrigins = [
'http://localhost:3000',
'http://localhost:3001',
'https://studio.apollographql.com'
];
const corsOptions = {
credentials: true,
origin: function(origin, callback){
if(!origin) return callback(null, true);
if(allowedOrigins.indexOf(origin) === -1){
var msg = 'The CORS policy for this site does not ' +
'allow access from the specified Origin.';
return callback(new Error(msg), false);
}
return callback(null, true);
}
}
app.use(cors(corsOptions))
var uri = "mongodb://localhost:27017/testmongo";
//@ts-ignore
mongoose.connect(uri, { useUnifiedTopology: true, useNewUrlParser: true })
.then(()=>console.log("connected to newmango db"))
//rest routes
app.get("/", (req, res) => {
res.json({
data: "API is working...",
});
});
const server = new ApolloServer({
typeDefs,
resolvers,
});
await server.start();
server.applyMiddleware({ app });
app.listen(PORT, () => {
console.log(` Server is running at http://localhost:${PORT}`);
});
}
startServer().catch(e=>console.log("error strting server======== ",e))
add the respective code and import it in the index.ts
The typedefs define what the data should look like and all it’s types
For example we have a custom type Item which is an object with the fields title of type Strung and desc of type String too
We also have to define the queries,mutations and subscriptions
These definitions are used to shape the data we’ll pass to and receive from our resolvers
Our resolver is comprised of a simple getItems query which returns an array of items from our mongo db
The addItem mutation takes title and desc and saves it to mongo then is returns an item response
has more information for more complex mutations and queries
but if you've noticeed my code is still full of //@ts-ignore decorators
because we are not using typescript it to it's fullest
next time we'll set up type-graphql and typegoose for better type-checking which makes development much easier
we'll also handle delete and update in mongodb
feel free to explore more till then
Top comments (0)