Writing your first Hello World microservice
Let's start by writing our first microservice. Based on the previous topics, we will construct our first microservice with best practices and the widely used node_modules. We will use:
So, open up a Terminal and create one Node project with a default package.json. Follow these steps. The full source code for reference is available in the first-microservice folder in the extracted source:
- First of all, we will download the preceding dependencies and basic express dependencies. Enter the following command lines:
npm install body-parser config cookie-parser cors debug express reflect-metadata rimraf routing-controllers typescript winston --save
- Download the types of necessary modules as follows:
npm install @types/cors @types/config @types/debug @types/node @types/body-parser @types/express @types/winston --only=dev
- Now, we will create our application structure, as shown in the following screenshot:
Folder structure
- So, let's create our express file and configure it using the routing_controllers module. Create one express config class and instruct it to use our directory controllers as the source from where it can find the routes:
export class ExpressConfig {
app: express.Express;
constructor() {
this.app = express();
this.app.use(cors());
this.app.use(bodyParser.json());
this.app.use(bodyParser.urlencoded({ extended: false }));
this.setUpControllers();
}
setUpControllers() {
const controllersPath = path.resolve('dist', 'controllers');
/*useExpressServer has lots of options, can be viewed at node_modules\routing-controllers\RoutingControllersOptions.d.ts*/
useExpressServer(this.app, {
controllers: [controllersPath + "/*.js"]
}
);
}
}
- Now, let's write our application startup logic inside application.ts:
export class Application {
server: any; express: ExpressConfig;
constructor() {
this.express = new ExpressConfig();
const port = 3000; this.server =
this.express.app.listen(port, () => {
logger.info(`Server Started! Express: http://localhost:${port}`);
});
}
}
- The next step is to write our controller and to return JSON:
@Controller('/hello-world')
export class HelloWorld {
constructor() { }
@Get('/')
async get(): Promise<any> {
return { "msg": "This is first Typescript Microservice" }
}
}
- The next step is to create a new object of our Application file inside index.ts:
'use strict';
/* reflect-metadata shim is required, requirement of routing-controllers module.*/
import 'reflect-metadata';
import { Application } from './config/Application';
export default new Application();
- You are all done; compile your TypeScript and start a transpiled version of index.ts. When you hit localhost:3000/hello-world, you will see JSON output—{"msg":"This is first Typescript Microservice"}.
- To add the automation of all the tasks while starting a server, we define scripts in our package.json. The first script is to always clean before transpiling:
"clean":"node ./node_modules/rimraf/bin.js dist",
The next script is for building TypeScript using the typescript version available inside the node modules:
"build":"node ./node_modules/typescript/bin/tsc"
The final one basically instructs it to clean, build, and start the server by executing index.js:
"start": "npm run clean && npm run build && node ./dist/index.js".
- The next step is to create a Docker build. Create one Docker file and let's write the Docker image script:
#LATEST NODE Version -which node version u will use.
FROM node:9.2.0
# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
#install depedencies
COPY package.json /usr/src/app
RUN npm install
#bundle app src
COPY . /usr/src/app
CMD [ "npm" , "start" ]
- We will learn about Docker in more detail in future chapters. Now, go ahead and enter the following command:
sudo docker build -t firstypescriptms .
Don't forget the dot at the end of the command while building the image. A dot indicates that we are using Dockerfile in the local directory.
Your Docker image will be built. You will see output like the following:
Docker create image
- You can use the sudo docker images command to check the image, which you can later use anywhere. To run the image, just use the following command line:
sudo docker run -p 8080:3000 -d firstypescriptms:latest
- After that, you can hit localhost:8080/hello-world to check the output.
While we just exposed the REST API, for the outer world it's just another service on port 8080; the inner implementation is abstracted from the consumer. This is one of the major differences between REST API and microservices. Anything within the container can change at any time.