NestJS + JWT: complete hands-on guide

In today’s article, we’ll be building a complete JWT-based authentication module with logout and refresh functionality. Also, we’ll get through on how to use access and refresh tokens with PassportJS and NestJS. But first, let’s understand how this mechanism works in theory.

Image generated by MidJourney AI for “json web token protects API from hacker attacks”
  1. After authenticating successfully the client receives an access token.
  2. The client provides an access token every time a protected request is made.
  3. The server checks if the access token is valid, if so, the request is successful.
  4. In case the token is invalid, the server throws an error about the token being invalid.
  5. The client is able to get a new access token by authenticating or refreshing it by presenting the refresh token.
  6. The server validates the refresh token, and if valid, issues a new access token and a refresh token.

Now that we have a solid grasp of how the mechanism works in theory, let’s try and put it into practice.

Prerequisites

In this guide we’ll be using regular REST for our endpoints and Prisma as our ORM system, we’re also gonna need a hashing library to hash users’ passwords and tokens — we’ll be using bcrypt.
For our authentication strategy, we’re gonna install nestjs/jwt and passport-jwt.

We won’t cover the project setup or the Prisma & JWT setup, since this is not the purpose of our today’s article. You could check the respective NestJS documentation if you need more details on this:

Once done with the basics let’s dive in by setting up our authentication controller:

And the authentication service should look like this:

Now let’s add our first method in our auth.service.ts to retrieve a user’s tokens, use env variables for the expiresIn field, the refreshToken expiration time is usually about a week and the accessToken expiration time should be about 15 minutes.

Let’s also add a method that will update a user’s hashedRefreshToken field, see more here.

Let’s implement the login functionality inside auth.service.ts, we’ll be using the above-implemented methods, signTokens and updateRefreshToken:

So what happens here is — that on each login, we supply the client with fresh tokens and update the current user’s state with a hashed token which will be used in the future to refresh both the refresh token and the access token.

Let’s implement both the logout and refresh methods, the logout method will delete the user’s stored hashed token and the refresh method will compare if the issued token matches the one stored inside the user, if that’s the case — it will issue the client a pair of fresh tokens.

Let’s move on to our auth.service.ts, see more here.

Pay attention that our logout and refresh method — received userId as a parameter, we’re not gonna pass that parameter inside the body of our request but rather get it from the JWT of the current user — we’ll achieve that by implementing both strategy and guard functionality (we’ll use the @nestjs/passport AuthGuard for now), it will help to manage the state of the authenticated users (by issuing JWT tokens in our case and verifying their credentials).

We’ll need 2 different strategies, one for accessing all the endpoints and one for our refresh endpoint.

The first strategy will decode the JWT from the request, by setting the ignoreExpiration to false — it will also check its expiration and send it back through the AuthGuard, so we’ll be able to access it from the Req() decorator (by default under the property user).

By setting the passReqToCallback to true inside the second strategy, we have access to the request object inside the validate method, the “refresh strategy” will take the refresh token from the authorization header and send it to the controller through the AuthGuard.

Let’s proceed by implementing our strategies first:

Now, let’s update our logout and refresh endpoints inside the auth.controller.ts, we’ll pass our newly created strategies to the AuthGuard which will be passed inside the @UseGuards decorator, thus our endpoints will be secured accordingly, that way we’ll create a connection between our endpoint and the created strategy and we’ll have access to the request object that is fulfilled with JWT data inside the strategy.

So let’s go once again through what’s happening really:

  • The logout endpoint is secured by our guard that implements the jwt strategy, thus it can be accessed only if the client provides a valid access token, if the access token is invalid — the refresh endpoint should be called by the client to ask for a new pair of tokens.
  • The refresh endpoint has one important job — to let the client refresh his tokens (without having to log in again), in case the provided refresh token by the client is not valid, the user is forbidden from accessing any endpoints other than login (in the case of our guide).

So now — we have our own refresh token mechanism implementation. This can be improved of course by creating a custom AuthGuard for both of our cases (access and refresh), we may also create a custom decorator that will return the JWT data from the ExecutionContext, instead of accessing the Req() decorator.

Bonus

Since we have the backend implementation, let’s try to go through the frontend part.
As was mentioned before, the client asks for new tokens using the refresh token as soon as the main token expires, and then the client needs to use the freshly retrieved token for the next API call until that token expires as well. You can send the request for new tokens after the first 403 response for example, but in this guide, we’ll be using Axios for the HTTP requests and Redis to store the tokens:

The response interceptor verifies if the server returned a status code that shows an access token has expired. If that’s the case, a function that refreshes the access token gets called. That function returns and stores the tokens in Redis.

References

People with Culture: bringing Mission and Values to life

In this article, we’ll talk about how a company’s values and culture help it implement its strategies and mission. We’ll start with some definitions and introductions and then will identify the possible issues and practical solutions.

Disclaimer: we’ll be using an IT company as an example, so some aspects may appear a bit subjective.

Values, Mission, Strategy

The mission defines the company’s global goal, while strategy leads to its implementation through culture and values.

To develop high-tech products the world and future you will be proud of — FusionWorks

Company values must change through the years. Not because the old ones were bad, but because they are bad for what the company represents now. This is a normal process of getting mature. Just see how Uber changed its initial ‘pirate’ values into more enterprise ones — or you may watch the “Super Pumped” series instead. The same changes we experience in our personal lives. Several times. If not — this is a sign to think your life over.

At FusionWorks, we are going through the same process over and over again, sometimes it’s painful and time-consuming. There are core values such as honesty, openness and inclusion that should not be changed, but upgrades are inevitable for lots of things you thought are here forever. I love this process, but you? Will be great to see your thoughts in the comments.

Values determine the company’s culture code. Here are some aspects of why culture is so important:

Culture is not the thing you write in the company’s employee handbook, it’s what people talk about when you are not around.

Strategy is a promise, corporate culture is the execution.

Culture eats strategy for breakfast.

Culture is formed around what you do, not what you say. If you say you are a company that values health and wellness but then brings in doughnuts every morning there is a disconnect. It’s fine to value doughnuts, who doesn’t love them but it’s not ok when your words don’t match your actions. It kills the trust you have in your team.

Job seekers are most likely to choose one job over another because of the chosen employer’s culture, according to talent acquisition professionals surveyed by the Korn Ferry Institute.

Having this said, a strong company needs to make sure it has its culture code and it’s working. At FusionWorks we use the people and culture approachwhich is a more progressive way of dealing with people. It is people-based, not policy-based.

If you treat people like people, they will be happier.

We can have a meaningful impact on people’s lives by giving them a working environment where they can be themselves and thrive. Understand and help your team grow together through positive activities and encouragement.

Manifesto

The manifesto is a more deliberate expression of your values and also supports the mission you have. It’s typically an emotional story that captivates your audience, emotionally connects with them, and persuades them to support your brand. It’s always a good idea to have it before we proceed to practical steps.

We build a no-bullshit company. No secrets, no lies, transparent, accountable, driven by facts, respectful to all. Openness in every aspect.

We love being tech-oriented and this infuses everything we do.

We believe being people-centric motivates and inspires much better than policies and control.

We are committed to being learning-driven, changing with the world, changing the world.

— FusionWorks

A practical guide to people-centric culture

First, let’s list the things that may make employees unhappy. It doesn’t mean your company has all of them, but they should be considered:

  1. Lack of progression and self-development.
  2. Unsatisfactory salary or benefits.
  3. Unhappiness with leadership.
  4. Lack of flexible schedules.
  5. Boring tasks.
  6. Negative experience/incident.
  7. Lack of recognition.
  8. Dissatisfaction with the company culture.
  9. A need for better work-life balance.

So here we go with implementing the People and Culture strategy. We aren’t forgetting about Human Resources, we value it and everything that goes along with it. HR is policies, procedures, and paperwork — all extremely important. But remember, People and Culture is people-based, not policy-based.

Once the employee has been onboarded (by the fabulous Human Resource team), it is time to improve their well-being, integrate them into the company, and show their value. This engagement improves productivity, creates a positive environment for the employee to thrive in, and generates happiness. Lower turnover, happier employees, and better work.

When we identify the issues, we may choose from the solutions below (not all of them work for all companies).

Supporting employees with talent and career development programs

  1. Implement the grading system — Roles and Levels — and make sure it’s well-defined.
  2. Assign employees to their current Levels. Explain their Roles.
  3. Clearly define the steps to progress to the next level.
  4. Revise the employees’ levels once in 6 months.
  5. Acknowledge employees’ successes.

According to LinkedIn, 94 percent of employees would stay at a company if it invested in their career development.

Development programs should be designed to ensure alignment between your expectations for top talent and the organization’s goals and vision. Professional development can include coaching processes, training seminars, networking opportunities, mentoring, special projects, and more.

Creating a more flexible schedule

The reason for that is the world trend toward remote work. So if it is possible with your company — consider it.

  1. Allow flexible schedule.
  2. Allow remote work if possible.
  3. Encourage a healthy work-life balance.

Many employees value a flexible work environment over compensation. In fact, 72 percent of employees would search for new opportunities if their schedule wasn’t flexible. Implementing changes to work policies can help improve retention rates.

Implementing a feedback and performance appraisal process

  1. Regularly get feedback from clients (once in 3-6 months).
  2. Pass feedback to employees.

Feedback is especially useful during the development of retention plans, and 82 percent of employees appreciate it. Feedback is essential in a remote environment; it establishes a benchmark for behaviors and skills and highlights what employees need to remain happy with their employer. Companies must be open to listening to employees and implementing changes and actions required to keep top talent.

Employee turnover can be reduced by up to 31% by managers acknowledging employee successes. Source.

Offering challenging projects where people matter

  1. Work with the clients directly.
  2. Work on interesting projects that matter.
  3. Make sure the clients listen to the voices of the employees.
  4. Make sure our employees are growing and learning on the projects.
  5. Fire bad clients.

Developing an effective employer branding strategy

Showing you are great or being great? Both. Showing your successes with no real wins doesn’t work long-term and leads to internal discontent. Being great without showing this externally won’t make the employees feel proud of the company, as well as your potential customers and employees won’t know how beautiful you are.

Companies are u̶g̶l̶y̶ copies of their founders.

People want to work in a company which grows together with them, faster than them. Also, they rarely work for those and with those whom they don’t respect at least professionally, who are weaker.

  1. Plan marketing strategy: current employees, potential employees, and customers.
  2. Communicate company strategy, mission and successes both internally and externally.
  3. Engage employees in the company’s activities.

According to a LinkedIn study, a strong employer brand can reduce turnover by 28 percent and the cost of hiring by 50 percent.

The communication and dissemination of the company’s image and actions are key to maintaining employees’ interest in remaining with the company and contributing to its success through specific projects.

46% of employees stated that a lack of transparent leadership communication is driving them to seek new employment. Meanwhile, 79% of highly engaged employees have trust and confidence in their leaders. Source.

Making culture work

  1. Clearly define the company’s mission, culture, and values.
  2. Show employees the big picture and goals.
  3. Explain mission and values.
  4. Believe in your mission and values. If you don’t believe — change them.
  5. Follow them — management should be an example.
  6. Show how mission and values work in practice.

Offering competitive benefits

  1. Offer what others have.
  2. Offer what others don’t have (to stand out).
  3. Offer benefits that make employee’s life comfortable and disappear when they leave the company.

Companies that offer competitive compensation and benefits can see 56 percent lower attrition. With the ever-changing labor market, companies need to adapt to employees’ evolving and growing needs and expectations. Nowadays, the most valuable benefits include remote work flexibility, employee discounts, time off, and financial advice.

Creating an open environment

  1. Encourage employees to speak and voice their concerns, ideas, and opinions.
  2. Treat all employees equally, on all levels. No favoritism.
  3. Treat your employees as you treat your best customers.
  4. Create an environment where everyone feels comfortable and safe.

No one wants to feel excluded in an organization they are a part of. New hire wants to feel like they were hired for a reason, and that they are playing a key role in helping the business achieve its objectives.

Josh Bersin, founder and principal at Bersin by Deloitte, found that companies who deliberately work to encourage inclusion, diversity, development planning, and leadership development in their culture were 3.8 times more likely to be able to coach people for improved performance, 3.6 times more able to deal with personnel performance problems, and 2.9 times more likely to identify and build leaders. Source.

Instead of epilogue

In the final chapter, I’d like to show you the FusionWorks values we believe in and share with the team. They determine our culture code:

Shared understanding in everything we do. Nobody has a monopoly on the truth. Decisions are made together and actions are reasoned on all levels.

People over processes. We encourage independent decision-making and believe in the power of freedom and responsibility.

Building cognitive diversity. Inventions are done by teamwork with people with different mindsets and competencies.

Building quality products. The things we do determine who we are, create our reputation step by step and reflect our eternal pursuit of excellence.

Learning never stops. We believe gaining knowledge is a continuous process and help you invest in your education for mutual benefit.

Sharing is caring. We share our experience — successes and failures — to help others learn and grow.

Building long-term relationships. Both our employees and clients are the people we want to work with long-term.

Learn, make impact, have fun. We always support initiative, awareness, quality, spirit and creativity. As simple as it sounds.

Like, comment, share — it’s always welcome!

The best version of employees — HOW and WHY

”…the most efficient way to make your employees happy is to understand their needs and mindsets.” — FusionWorks

A happy employee is a productive one. This is why it is very important to understand what makes not any, but YOUR employees happy. Knowing the individual motivators we may share care and strengthen what really matters.

Yes, it is priorly to allocate resources for employees’ motivation. What drives someone starts with communication. An empathic, non-violent (reading recommendation), and assertive one — this is when we learn to understand our employees, not only pretend we do. Mental and physical health at work is totally dependent on the working atmosphere. If you need a healthy employee you have to work on his / her well-being. This is a long process. Do not be scared or afraid when results will need time to be seen. This is normal. Below will be listed some crucial axioms to control and influence your employee motivation and in this way — to help them become the best versions of themselves. All of these were summarized while tested in time, on different employees (the difference was in one or some of these factors: age, gender, interests, temperament, education, and background), and could be used as steps for employee-admiration.

  1. When satisfaction and benefits are in a correlation with work-volumewe see a happy employee. We may easily monitor this correlation with 3 simple tools: 1–1’s, onboardings, performance review (in ideal cases onboardings and performance review meetings will be conducted by TL & HR), questionnaires (with direct questions and metaphorical ones, anonymous and not). Honestly, first in this list is my favorite tool, as during 1-on-1 it is very easy to understand the person you interact with. And this is much more than words. Here every single gesture is special and every single selected topic is crucial. Without a psychological background, things could be a little more challenging, but we are so lucky! A lot of information is available online and after some search and good reading — anyone could coordinate an awesome 1–1. Another advantage is that no 1-on-1 is the same. So, this kind of discussion is fascinating!

This article is powered by Empy.io — an all-in-one tool that helps HRs synchronize with the employees and handle all the internal requests in one single place. Try it for free!

2. Leaders influence employees. All of us need approval, no matter how old or how experienced we are. Being in a room where you have a leader, you need to understand that he/she is here for you. That you may ask anything and you will receive the needed / correct answer. The easiest way to influence your employees positively is to be an example they would love to follow: do not be afraid to ask for help (we are all humans, we all need help sometimes with something, and this is normal), do not doodle from answering questions (even if tricky ones. Find a real response and operate with it). If you want something to be changed, be the first who not only is ready for a change but has already begun this brilliant process: take different tasks, enroll in different pieces of training and projects (why not along with your employees).

3. A constructive, positive, and empathic attitude towards your employees encourages them to express their ideas and visions freely, to communicate as openly as possible, without fear of making mistakes or being judged. They said people never leave jobs, they leave bosses or teams. So help your team be the one everyone dreams to become a part of. Steps to be taken: grow a collaborative work-culture (team responsibility — team decisions, brand bearers while participating in different non-work-related activities), cherish your team (praise concrete behavior, encourage employees individuality, create a context for creativity expressing).

The most important, but at the same time, the most beautiful way to make your employees happy is to understand everyone’s needs and mindsets. Knowing what drives every single employee, investing in his/her wellbeing, we will reach the win-win solution: a happy employee is a productive one, a productive one is a valuable one, a valuable one is the loyal one. Loyal employees are the treasure any respectable company deserves.

Dear Procrastination, let’s break up!

“… procrastination is a well-known process: we leave the tasks for the last moment, then we panic.”

Your deadline is here. But your task is not in progress, it is not even started yet. And you do not rush to do it. You may recheck a 10th time if you have a new message. You may remind yourself about a very interesting video that must be reseen at this very moment. You are hungry. You have to respond to an urgent call. Yes, you understand that you need to work. Also you, as a rational being, understand that you have to force yourself to start this task/activity. But it is simply impossible. Yes, procrastination is a well-known process. We leave the things we have to do for the last moment, then we panic. Do you remember the Panic Moster Ted talk? This habit destroys us, but what would be the solution? Here are some options:

This article is powered by Empy.io — an all-in-one tool that helps HRs synchronize with the employees and handle all the internal requests in one single place. Try it for free!

1. Divide everything you need into small pieces. They say it is impossible to eat an elephant, but it could be done by breaking it into small pieces. One of the causes of procrastination is the understanding, on a subconscious level, of the excessive volume of the task. Focusing on small things we will be willing to quickly finish what we set out.

2. Change the work environment. Different environments have different impacts on our productivity. Choose where it is easier for you to do a certain activity.

3. Draw up a calendar and set deadlines for every particular activity. Having a single deadline for all activities is like an invitation to procrastinate.

4. Eliminate distracting factors. One of the reasons for procrastination is the availability of other occupations, so limit your access to what distracts you. Put the phone on silent, close all tabs where you do not work, do not leave any opportunity to escape!

5. Communicate with people who inspire you to action. The people in our entourage directly influence our behavior. By interacting with other people, each of us takes something from the interlocutor.

6. Clarify your goal. Maybe the cause of procrastination is the discrepancy between what you want to achieve and what you do. It happens that during our journey in reaching the goal, we grow and we already have other desires and needs. Instead of wasting time, take a break and decide what you really want to achieve.

7. Don’t complicate things. Are you waiting for a perfect time to start? Now is not the right time to start because x, y, z? Here’s a secret — the perfect moment will never be or is right now, you choose!

Wix + Viar.Live: VR websites made easy

Several years ago we at FusionWorks launched our awesome tool for 360° photographers — Viar.Live. Its goal was to offer an easy-to-use tool for creating virtual tours from 360° photos. Viar.Live was warmly accepted by the users and we got a lot of positive feedback, but one email really surprised us: we were approached by Wix with the suggestion of joining their app market with our application, which we eagerly accepted. The journey was not easy since Wix has a lot of specific requirements with which we had to comply, but finally we made it through and now it’s time to present the results.

Finding the Virtual Tours app on the market place

Just type “Virtual” in the Wix App Market or follow this link and add our app to your website.

Creating your first tour

To create a tour you don’t need to specifically create a 360° photo — any panorama made on your smartphone will work. Just click “Get Started” in the application settings and upload your photos.

Once the uploading and processing are over, click “Continue” to proceed to the tour editor. Once in it, start connecting panoramas by dragging thumbnails into appropriate connection places.

Besides connection points, you can also add link and information hotspots.

Once finished, just assign a newly created tour to the Virtual Tours widget and share your website!

Have a great day!

Genadii Ganebnyi,
CEO @ Viar.Live

5 Easy Steps To Improve Your Productivity

“Let’s Work Smarter, Not Harder” — FusionWorks

If you work hard and spend a lot of time on an elementary task, it does not mean that you are productive. Firstly let’s try to analyze what productivity is.

Productivity is commonly defined as a ratio between the output volume and the volume of inputs. Or, the rapport between completed tasks and the time spent while completing them. Employee productivity (sometimes referred to as workforce productivity) is an assessment of the efficiency of a worker or group of workers. Typically, the productivity of a given worker will be assessed relative to an average for other employees doing similar work.

Now, when we have an idea of the productivity concept we may think about the ways to improve it. Try the following and you will definitely increase efficiency! Let’s start working smarter instead of harder:

This article is powered by Empy.io — an all-in-one tool that helps HRs synchronize with the employees and handle all the internal requests in one single place. Try it for free!

1) Finish planning. Start acting.

It’s good to take the time to plan your actions, but you can waste too many hours just planning. Check what you have to do and don’t wait, start! If you count tens of thousands of times the activities you have to undertake, you gain nothing. Avoid friendship with procrastination, break with it! You can do it. Start the activity. A small step is still a move forward.

2) Meetings can last a maximum of 30 minutes.

Are all the meetings so important? Who counted how many hours a week he/she spends for: on the way to/from the meeting, unimportant discussions, boring people? If you have what to skip, do it. But if you are sure of the importance of all meetings, drop them on time. Half an hour is the perfect time to find out the latest news, decide and go on happily.

3) Say YES only to the important things.

Someone said that the difference between a successful man/woman and a very successful one is the ability to say NO. Every time we agree to do something for another person, we waste our time on activities that have absolutely nothing to do with our mission and goals. As a result, we are unhappy. We have not achieved anything important. We are tired — half a day has passed for nothing. And we are depressed — we do not find meaning in what we do. We can achieve more if we only get involved in what matters, we know exactly what we do when we do it and why we do it.

4) Free your mind.

Our brains are overworked. We bombard them with all kinds of information and more and more voluminous. Why do we remember what we only need for a very short time? Why were all kinds of diaries invented? When we want our computer/phone to work faster, we get out of all sorts of unnecessary applications, as well the mind works. Everything we can write — meetings, classes, topics for discussion, questions, etc. — write down instead of trying to memorize.

Organizing the biggest IT event in the most promising European country

Prolog

IT is always about communities. Such was my thinking in the far year of 2011 when I created the first Moldovan IT community on Facebook — DeveloperMD. After a half-year of online activity we decided that we have to get together offline. Said and done: in September 2011 we had the first DeveloperMD Community Offline with approximately 40 participants. One week later me and my partner created a software development company — FusionWorks — this was inspired by the outcome of the first event. Already in November, now having FusionWorks as the main partner, we’ve organized the 2nd edition. At some point, due to the growing size of the event, we realized that it should be done once a year and eventually we had 11 editions so far. In 2018 the big change took place — event was extended to two days, the name was changed to Moldova Developer Conference and another, much bigger venue, was selected. This led to the increase of number of participants — 350 — which makes MDC the biggest IT conference for developers in the country. This year #MDC19 is planned for November 2–3 and we expect around 450 awesome people to attend. So let me tell you more about what is going to happen in 2019.

Why #MDC19 is cool

Well, let’s count:

  1. It’s the biggest IT event for developers in the country.
  2. It has thoroughly selected content (speakers pass through a selection process and are trained by professionals).
  3. Each conference day is followed by amazing afterparty or wine tasting event (yep, Moldova is about wine and IT — not sure which one comes first).
  4. The entrance fee is more than affordable (thanks to our partners!).
  5. Theory is not everything, we have practical workshops from international experts!

Still not sure? Just watch this video from 2018. Like it? Then read more below 🙂

How to get onboard

Simple!

  1. Book the flight and accommodation (if you are not living here).
  2. Buy the ticket or apply as a speaker or partner.
  3. Get latest updates on our website and Facebook event page.
  4. Come to the event on November 2–3.
  5. Enjoy!

Why doing this?

Sometimes people ask: “Why are you doing this?”. The answer simple — we do it because we can. And because we love it! Having hundreds of bright eyes before you is the pleasure that can’t be denied. So we started in 2011 and are not going to stop.

Ok, let’s now learn more about the host country — Moldova — this small IT valley.

Top 3 facts about Moldova

  1. Moldova is not Maldives. Often mail delivery companies send parcels to the wrong country. Moldova has around 3.5 millions inhabitants and used to be USSR country until 1991. Official language is Romanian/Moldovan (the same language but is called differently in official documents). Also people understand and speak Russian here. Most of IT geeks speak English fluently, taxi drivers — not.
  2. Moldova has a very attractive IT sector — companies pay unique 7% tax that transforms BRUT into NET. IT sector capacity is about 10 000 specialists. Most of the companies are outsourcing ones and offer very attractive rates.
  3. The highest peak in Moldova is 428 meters high and the author of this article has never climbed that hill. Despite the fact that he has been to Everest BC, Kilimanjaro, Elbrus, Kazbek, Mitikas/Olimp and many others.

See you in the most promising IT country in Europe!

Anton Perkin, CEO at FusionWorks

Creating admin-like web applications with NestJS and React Admin. Part 1.

Introduction

In this series of articles, I will describe how to quickly bootstrap an API-based administration panel for your project using NestJS and React Admin.

In order to proceed further (in casу you are not reading just for fun), you may need to have NodeJS 10+npmyarn and MySQL installed on your computer. Also, you should have some basic knowledge of TypeScript and React.

Our project will consist of 2 part:

  • REST API, written in TypeScript
  • Admin panel, written in React

For demo purposes, we will create a simple application for managing guests list. This will include creating guests, showing list and updating guests info.

So let’s start.

Creating API

For creating API we will use NestJS framework. I enjoy NestJS because it is TypeScript based and thus allows producing better readable, better structured and less error prone backend code.

We will use NestJS CLI tool to initialize our backend:

npm i -g @nestjs/cli
nest new api
cd api

Now when the project skeleton is ready we will add other dependencies we need.

We will use TypeORM (again TypeScript) for working with MySQL:

yarn add @nestjs/typeorm typeorm mysql class-validator class-transformer

NestJS CRUD library to simplify our endpoints creation:

yarn add @nestjsx/crud

And NestJS Config for managing our application configuration:

yarn add nestjs-config

Once done with dependencies lets generate the skeleton of our Guests API endpoint

nest generate module guests
nest generate controller guests
nest generate service guests

And create a model class for our guest entity (src/guests/guest.entity.ts)

import { Entity, Column, PrimaryGeneratedColumn } from ‘typeorm’;
import { IsEmail } from ‘class-validator’;

@Entity({ name: 'guests' })
export class GuestEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
firstName: string;

@Column()
lastName: string;

@Column({
unique: true,
})
@IsEmail()
email: string;

@Column({ default: false })
isPresent: boolean;
}

Now we add some code to wire parts together

Update src/guests/guests.module.ts with TypeORM dependencies

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { GuestsController } from './guests.controller';
import { GuestEntity } from './guest.entity';
import { GuestsService } from './guests.service';
@Module({
imports: [
TypeOrmModule.forFeature([GuestEntity]),
],
controllers: [
GuestsController,
],
providers: [
GuestsService,
],
})
export class GuestsModule { }

Make src/guests/guests.service.ts extend RepositoryService from NestJS CRUD

import { Injectable } from '@nestjs/common';
import { GuestEntity } from './guest.entity';
import { RepositoryService } from '@nestjsx/crud/typeorm';
import { InjectRepository } from '@nestjs/typeorm';
@Injectable()
export class GuestsService extends RepositoryService<GuestEntity> {
constructor(@InjectRepository(GuestEntity) repository) {
super(repository);
}

}

and add it to src/guests/guests.controller.ts. Also, add Crud decorator to the controller in order to enable NestJS CRUD API-related features.

import { Controller } from '@nestjs/common';
import { Crud } from '@nestjsx/crud';
import { GuestsService } from './guests.service';
import { GuestEntity } from './guest.entity';@Crud(GuestEntity)

@Controller('guests')
export class GuestsController {
constructor(public service: GuestsService) { }
}

Finally, we configure TypeORM in the main module (src/app.module.ts):

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from 'nestjs-config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { GuestsModule } from './guests/guests.module';
import * as path from 'path';@Module({
imports: [
ConfigModule.load(path.resolve(__dirname, 'config', '*.{ts,js}')),
TypeOrmModule.forRootAsync({
useFactory: (config: ConfigService) => config.get('database'),
inject: [ConfigService],
}),
GuestsModule,
],
controllers: [
AppController,
],
providers: [
AppService,
],
})
export class AppModule { }

And add the appropriate configuration files

src/config/database.ts:

export default {
host: process.env.DB_HOST,
type: 'mysql',
port: process.env.DB_PORT || 3306,
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
entities: ['src/**/*.entity{.ts,.js}'],
synchronize: process.env.DB_SYNCRONIZE === 'true',
logging: process.env.DB_LOGGING === 'true',
};

.env:

DB_HOST = localhost
DB_PORT = 3306
DB_USER =
DB_PASSWORD =
DB_DATABASE =
DB_SYNCRONIZE = true
DB_LOGGING = true

And we are ready to start!

Not so fast 🙂 Later on React Admin will require CORS to be enabled on API side. So we need to modify src/main.ts. And by the way lets make React’s life easier and free 3000 port!

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule, { cors: true });
await app.listen(3001);
}
bootstrap();

Now it is really ready!

yarn start

and continue to creating out administration panel UI.

Creating Admin UI

As mentioned before for this purpose we will use React Admin — a React based component library for creating admin-like interfaces.

Let’s start with initializing a React applicationn

pm install -g create-react-app
create-react-app admin-ui
cd admin-ui

Then add React Admin to the project

yarn add react-admin prop-types

and a small library developed by us (FusionWorks): @FusionWorks/ra-data-nest-crud, which integrates React Admin with our NestJS CRUD-based backend.

yarn add @fusionworks/ra-data-nest-crud

After this we are redy to initializing React Admin component and create guest editor. First, we update src/App.js with root Admin component and Resource component for guests:

import React from 'react';
import { Admin, Resource, ShowGuesser, ListGuesser } from 'react-admin';
import crudProvider from '@fusionworks/ra-data-nest-crud';
import { GuestCreate, GuestEdit } from './Guests';const dataProvider = crudProvider('http://localhost:3001');
const App = () => (
<Admin dataProvider={dataProvider}>
<Resource name="guests" list={ListGuesser} create={GuestCreate} edit={GuestEdit} show={ShowGuesser} />
</Admin>
);
export default App;

Then add corresponding forms to src/Guests/index.js.

Please note that we are using React Admin’s ListGuesser and ShowGuesser for list and show veiws. If needed they could be replaced with custom implementation same way as create and edit forms below.

import React from 'react';
import {
Create,
SimpleForm,
TextInput,
BooleanInput,
Edit,
Filter,
required,
email,
} from 'react-admin';const validateEmail = [required(), email()];
const validateRequired = required();export const GuestCreate = props => (
<Create {...props}>
<SimpleForm redirect="show">
<TextInput source="firstName" validate={validateRequired} />
<TextInput source="lastName" validate={validateRequired} />
<TextInput source="email" validate={validateEmail} />
</SimpleForm>
</Create>
);const GuestEditTitle = ({ record }) => (<span>{`${record.firstName} ${record.lastName}`}</span>);export const GuestEdit = props => (
<Edit {...props} title={<GuestEditTitle />}>
<SimpleForm redirect="list">
<TextInput source="firstName" validate={validateRequired} />
<TextInput source="lastName" validate={validateRequired} />
<TextInput source="email" validate={validateEmail} />
<BooleanInput source="isPresent" />
</SimpleForm>
</Edit>
);

Once done with this, we are ready to rock!

yarn start

Conclusion

So far everything looks great, but we have not yet touched such things as authentication, authorization, cases when database and API models should differ, etc. I will cover them in the next articles and we’ll if this stack survives nicely. So stay tuned to the FusionWorks:

Useful links

Source code for the article: https://github.com/FusionWorks/nestjs-crud-react-admin-boilerplate

If you want to dive dipper yourself here is the set of links to documentation that might be useful for you: