Make a simple Fastify API with TypeScript and deploy it
Tags: typescript, fastify, deployment, api
Published: 2022-04-14 07:58:18

In this tutorial, we will see how to build a simple API with Fastify and TypeScript, and how to deploy it on the ScaleDynamics Platform.

## Introduction

[Fastify](https://www.fastify.io/) is a Node.js web framework for building HTTP APIs. It is designed to be easy to use, and to be fast. It has a powerful plugin architecture inspired by Express and Hapi. It is design with developper experience in mind without sacrificing performance.

## Goals

Our goal will be to build a simple starting point for a Fastify API with TypeScript that will return some users fetched from [jsonplaceholder](https://jsonplaceholder.typicode.com/). Then we will deploy it on the ScaleDynamics Platform to be able to use it from any application.

## Prerequisites

To follow along, you will need:

- Node.js and yarn / npm installed. You can go [here](https://nodejs.org/en/download/) to download the latest version of Node.js and npm
- Some basic [TypeScript](https://www.typescriptlang.org/) knowledge

## Setup the project

Let's create a folder and initialize a npm:

```shell
mkdir fastify-api
yarn init
```

Don't bother with the options in the prompt, you can directly use this code in your `package.json` file:

```json
{
  "name": "fastify",
  "version": "1.0.0",
  "main": "src/index.ts",
  "license": "MIT",
  "scripts": {
    "build": "tsc -p tsconfig.json",
    "start": "node ./dist/index.js"
  },
  "dependencies": {
    "@types/node": "^17.0.23",
    "axios": "^0.26.1",
    "fastify": "^3.28.0"
  },
  "devDependencies": {
    "typescript": "^4.6.3"
  }
}
```

Install the dependencies by running:

```shell
yarn
```

Now we need to create a `tsconfig.json` to configure TypeScript, so let's run:

```shell
npx tsc --init
```

We need now to make some changes to it:

```json
{
  "compilerOptions": {
    "target": "esnext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
    "module": "commonjs" /* Specify what module code is generated. */,
    "outDir": "./dist" /* Specify an output folder for all emitted files. */,
    "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */,
    "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
    "strict": true /* Enable all strict type-checking options. */
  }
}
```

The project is now ready, let's build our API:

## Build the API

Create a `src` folder at the root of your project, and create a `index.ts` file inside it:

```ts
import axios from "axios";
import fastify from "fastify";

const server = fastify();

server.get("/users", async (): Promise<User[]> => {
  return (await axios.get("https://jsonplaceholder.typicode.com/users")).data;
});

server.listen(8080, (err, address) => {
  if (err) {
    console.error(err);
    process.exit(1);
  }
  console.log(`Server listening at ${address}`);
});
```

Our API will simply return a list of users fetched from [jsonplaceholder](https://jsonplaceholder.typicode.com/) when we call `/users`.

We need to add the definition of the `User` type, so create a `domain` folder and a `user.d.ts` file inside:

```ts
type User = {
  id: number;
  name: string;
  username: string;
  email: string;
  address: Address;
  phone: string;
  website: string;
  company: Company;
};

type Address = {
  street: string;
  suite: string;
  city: string;
  zipcode: string;
  geo: Geolocalisation;
};

type Geolocalisation = {
  lat: string;
  lng: string;
};

type Company = {
  name: string;
  catchPhrase: string;
  bs: string;
};
```

We can now build our code to transform it into JavaScript and run it:

```shell
yarn build
yarn start
```

Try to get the users by running:

```shell
curl localhost:8080/users
```

You should dump the users like:

![user dump](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dqbk7u894lkv775rca0n.png)

Perfect ! Now let's deploy our API on the ScaleDynamics Platform.

## Account creation and resource selection

To deploy this application on ScaleDynamics's cloud, you need an account and create an environment with a resource for it. The cloud resource provides virtual CPU and storage capacities used to execute the app. In this tutorial we will use a free shared resource available on ScaleDynamics’s cloud. These are the best one for testing. In this tutorial we will see later how you can upgrade to a dedicated production resource on the public cloud provider and region of your choice.

If you don't have an account, feel free to create one [here](https://console.scaledynamics.com/auth/signup/) (it's free and no credit card are required). Once your account is created, sign in.

Let's create a project and an environment on the ScaleDynamics's [console](https://scaledynamics.com/console). Select your organization, create a new project, then create a new environment. Now we need to choose what kind of service we need for our deployment. There are four types:

- managed HTTP docker
- managed Node.js server
- managed Node.js module
- static assets hosting

For our API, we need a server. Let's pick the managed Node.js server. You can learn more on the other types in the [ScaleDynamics documentation](https://docs.scaledynamics.com/).


![env creation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qtdflv117unipzd7tpgl.gif)

## Deployment

The environment is ready to run our application, let's deploy on it.

### Configuration file

First, let's add a configuration to tell the SDK what type of application we want to deploy. At the root of the project, create a `warp.config.js` file:

```javascript
// warp.config.js
module.exports = {
  server: "fastify",
};
```

### Build

Build the project to compile the TypeScript code into JavaScript:

```shell
yarn build
```

### Login

Log into your account and select your organization via the prompt:

```shell
npx warp login
```

### Deploy

Finally, we can run the deployment command:

```shell
npx warp deploy ./
```

This command will dump something like this:


![deploy dump](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jhfxsr9kswxm6c0ol94h.png)

You can see that a server was detected from your configuration file. Now follow the prompt, select the project you created, then the environment. The prompt will also ask you for a hostname, you can leave it blank for a random name or use the one you want. Finally, you can select a host.

The deployment will take a few minutes.

When it's done, you can open your browser and go to the URL and TADA ! Your API is live !

## Go further: dedicated resources

If you want to use dedicated resources, you can upgrade dynamically to a non shared resource. As shown below it's as simple as a few mouse clicks.

![Upgrade to dedicated](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o91zuvj5ag49elxiydcn.gif)

## Next steps

At this stage, you have a fully functional API. You can learn more on the ScaleDynamics [documentation](https://docs.scaledynamics.com/), like how to get the logs of your server, use a custom domain, implement a CI/CD pipeline, etc.

Enjoy !