DEV Community

Gracious Obeagu
Gracious Obeagu

Posted on

Overcoming a Challenging Backend Problem with TypeScript: My Journey and Aspiration

Introduction

As a backend developer, you must solve complex challenges on a regular basis, but every now and then, a particularly difficult problem emerges that tests your expertise and inventiveness. I recently experienced such a situation while working on a project, and I'd want to share my experience with it, particularly my first use of TypeScript to address it. This experience is very relevant to me as I prepare to embark on a new adventure through the HNG Internship, which I am really enthusiastic about. By the way you can read about HNG here

The Problem

I was required to build an API for an app that requires, Two-Factor Authentication (2FA) system. This system will also store images and send activation links upon registration to the user's email and so on.

Full breakdown of the features:

  • Upon registration, a user receives a confirmation email and proceeds to log in.
  • The login process involves 2FA, where a user enters their email address, a six-digit One-Time Password (OTP) is generated and sent to the provided email address.
  • Using in-memory cache, Redis, or a database to store the OTP, which expires after 5 minutes,
  • All Users using the App must have API keys.
  • Files can be uploaded using the API key.
  • If not already done, users must generate an API key to upload files.
  • Uploaded files must be associated with the user who owns the API key.
  • Only image files are allowed currently and should be stored as Base64 strings in the database.
  • Files should be deleted from the system/app folder after being stored.
  • And finally writing a README that is up to date.

My Initial Approach

The first step was to have a quick crash course on how to use Typescript in Node/Express JS. Armed with this information, I also looked up how to use in-memory databases like redis for caching things like OTP.

Diving Deeper with TypeScript (My Thought Process)

Using TypeScript for the first time, having heard about its benefits in terms of type safety and improved developer experience, I thought it would be a good opportunity to learn and apply it.

I Wrote the Authentication and Authorization for the APP, used a Package called Nodemailer for sending activation link for registration and OTP (2FA) to the user when the user logs in.

Generating API-Keys, this was another torn in the flesh as I have never done something like this before, but after careful consideration, I decided I was going to use Middleware to handle it. So when the user creates an account, activates the and logs in an API-KEY is generated. This API-KEY can now be used by the user to make any file upload, The user can also delete and existing API-KEY and create another one

Database Relationship was crucial as it helped me to know which user uploaded an image so I used One-to-many relationship to achieve this feature, so I have an image schema with image-filename, base64 string and user-id properties

I also wrote a logic that makes it impossible for a user to upload a file that is not an image and also store this file in base64 for better optimization as saving image directly to the database isn't a good approach and can make the system lag.

The Image file after been converted to base64 string is deleted from the system/app folder

A well documented Readme file that can help anyone using the app to read and understand the flow

Setting Up TypeScript

First, I set up a TypeScript environment in my project. This involved installing TypeScript and configuring the tsconfig.json file to enable strict type-checking and other beneficial options.

json
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}

TypeScript Interfaces

Using TypeScript’s type definitions helped ensure that the data structures were well-defined and that the query results matched the expected types.

typescript
interface Product {
base64: string;
user_id: ObjectID;
}


Indexing: I added appropriate indexes to the columns frequently used TypeScript helped manage these database schema changes more reliably by ensuring the consistency of column names and types across the codebase.

Caching with TypeScript: I implemented caching for frequently accessed data. By storing the results of these queries in a Redis cache, I especially used this in sending OTP to help reduce the load on the database and speed up response times for repeat requests.

Testing and Validation

After making these changes, I thoroughly tested the system to make sure there is no loose ends and properly captured all the operational errors that might occurs by sending a meaningful response to the user of any error that might occur

Reflection

This experience reinforced several key principles for me: the importance of detailed diagnostics, the power of optimization, and the value of perseverance in problem-solving. It also highlighted the need for continuous learning and adaptation in the ever-evolving field of backend development. Using TypeScript for the first time was a game-changer, providing a robust framework for writing reliable and maintainable code.

Looking Ahead: The HNG Internship

As I look forward to starting my journey with the HNG Internship, I am filled with excitement and anticipation. The HNG Internship represents an opportunity to further hone my skills, collaborate with talented individuals, and contribute to impactful projects. I am eager to bring my problem-solving mindset and technical expertise to the table, while also learning from the diverse experiences and insights of my peers and mentors.

Why HNG?

I believe that the HNG Internship will provide a unique platform to grow both professionally and personally. The program’s emphasis on real-world projects, mentorship, and community aligns perfectly with my aspirations. I am particularly drawn to the collaborative environment and the chance to work on innovative solutions that can make a difference. Have you heard about HNG hire? You can read about it here

Conclusion

Solving difficult backend problems is not just about technical skills; it’s about persistence, creativity, and a willingness to learn. As I prepare for the HNG Internship, I am excited to tackle new challenges, build meaningful connections, and continue my journey of growth and discovery in the world of backend development.

Top comments (0)