Routing Controllers with MongoDB tutorial

Table of contents

This is a guide to setting up Routing Controllers (a very simple npm package to run an express server) with MongoDB.

I have a guide on setting up routing-controllers from scratch here.

So if you are following along, make sure to run through that first to set up the initial routing-controllers server.

This page will now focus on what you need to do to run a mongodb server in your routing-controllers app.

Where to get an instance of MongoDB

For easy development I would recommend first trying out railway.app. I'm in no way sponsored by them... they just have a great interface to instantly deploy a small mongodb server (for free).

Some shortcuts I'm taking for this tutorial

This is a basic tutorial showing how to set up MongoDB in a routing-controllers app. I'm going to skip anything like DI (Dependency injection), and just use a very basic mongoose setup.

I'm also going to put all of the schemas in one file, and re-use our existing controller. I also won't use good RESTful examples. But this should make this easy to copy/paste and you can refine it into something more production ready!

I'm also going to hard code in the mongodb connection string. do not do this in a real app! use environment variables.

Install mongoose

Assuming you already have routing-controllers, express, etc set up then all you will need to do is install mongoose:

yarn add mongoose

Now let's create a schema for our MongoDB collections....

Create a file in ./src/schemas.ts

(for a real app: don't put them all in this file!)

And paste in this code, which uses mongoose to set up a schema for a blog post object:

import mongoose from "mongoose";

const BlogPostSchema = new mongoose.Schema({
    title: {
        type: String,
        required: true,
    },
    views: {
        type: Number,
        required: true,
    },
    isPromoted: {
        type: Boolean,
        required: false,
        default: false,
    },
    body: {
        type: String,
        required: true,
    },
});

export const BlogPost = mongoose.model("BlogPost", BlogPostSchema);

Connect to a mongodb database

Create a file ./src/database.ts and add this function to connect to mongodb via mongoose:

const mongoose = require("mongoose");

export const connectToDatabase = async () => {
    try {
        console.log("Connecting to db");
        // get this url from railway.app - copy the full url with username/password.
        // DO NOT DO THIS IN A PRODUCTION APP
        // USE ENVIRONMENT VARIABLES AND DO NOT COMMIT THE PASSWORD TO YOUR GIT REPO...
        await mongoose.connect(
            "mongodb://mongo:YOUR_USERNAME@YOUR_HOSTNAME" // FOR DEVELOPMENT ONLY!
        );
        console.log("Connected to db")
    } catch (error) {
        console.error(error);
        process.exit(1);
    }
};

And in your server.ts, add this:

// src/server.ts
import { createExpressServer } from 'routing-controllers';
import {HelloWorldController} from './controllers/HelloWorldController';
import {connectToDatabase} from "./database"; // << import this

const PORT = 4000;

async function start() {
    console.info(`Starting server on http://localhost:${PORT}`);

    const routes = [HelloWorldController];

    await connectToDatabase() // <<< add this

    const app = createExpressServer(
        {
            controllers: routes,
        }
    );

    app.listen(PORT);

}

start();

Now use the mongodb data in your controller

I'm going to reuse the existing hello-world controller.

// HelloWorldController.ts
import {Controller, Get, Param, QueryParam} from 'routing-controllers';

import 'reflect-metadata';
import {BlogPost} from "../schemas";

@Controller('/hello-world')
export class HelloWorldController {
    @Get('/posts')
    async posts() {
        const allPosts = await BlogPost.find();

        return {data: JSON.stringify(allPosts)}
    }

    // for tutorial, adding this on a GET request
    // but of course you would want this on a POST request, behind auth!
    @Get('/new-post')
    async newPost() {

        const newRandomPost = new BlogPost({
            title: "A new post added on " + new Date(),
            body: "Some blog post content here " + Math.random(),
            views: 0,
            isPromoted: Math.random() < 0.5
        })
        const insertedPost = await newRandomPost.save();

        return JSON.stringify(insertedPost)
    }

    // again for tutorial this is not following good RESTul urls!
    @Get('/single-post/:id')
    async singlePost(@Param('id') postId: string) {
        const allPosts = await BlogPost.findById(postId);

        return {data: JSON.stringify(allPosts)}
    }

    @Get('/index-html')
    async indexHtml() {
        const allPosts = await BlogPost.find();
        const html = allPosts.map(post => `<div>
            <h1>${post.title}</h1>
            <a href='/hello-world/single-post-html/${post.id}'>link</a>
        </div>`)
        return html.join("\n");
    }

    @Get('/single-post-html/:id')
    async singlePostHtml(@Param('id') postId: string) {
        const post = await BlogPost.findById(postId);
        const html = [
            `<h1>${post.title}</h1>`,
            `<div>${post.body}</div>`,
            `<div>Views: ${post.views}</div>`,
        ]
        return html.join("\n");
    }
}

(make sure you are still including this controller in your routing-controllers server set up (within your createExpressServer call - see my previous tutorial for info)

Now visit your server

Visit http://localhost:4000/hello-world/posts and you should see the empty array.

Visit http://localhost:4000/hello-world/new-post and it will generate and save a new dummy post.

Visit http://localhost:4000/index-html to see a list of your posts, with a clickable link

Next steps

This is a short introduction to set up routing controllers with MongoDB - but for a real app you will want to clean it up and organise your schemas/connection better.

These are some of the steps I'd do next but are out of scope of this tutorial.

Comments Routing Controllers with MongoDB tutorial

(To comment without signing up to Disqus, fill out your name (under "or sign up with disqus") and press "post as a guest" in the button that appears!)