Building my Full-Scale Web Application
by Rishi Collins | May 15, 2022
I built my first full-scale web application with node.js and many of its frameworks. Here's how I conquered this journey, from a mere idea to full creation.
Features and Frameworks
For this project, I used node.js, and the entire codebase is written in TypeScript and JavaScript.
For the Front-end
- React (CRA-based)
- Material UI (MUI)
- Axios HTTP Client
Now, the Back-end
- Express.js for API server and routing
- MongoDB Cloud for Database storage
- Custom-built authentication system based on JWT's (jsonwebtoken)
- Custom generation scripts with the help of passkit-generator
I wanted to build a digitized version of the ID card I use at school for door access and internal payments. I looked at all the possibilities for making this a reality. In turn, I found that I can do it right from node.js thanks to the help of the passkit-generator npm package.
I created an Apple Developer account to get my service credentials and required certificates and installed them on my computer. This process is somewhat tedious, but once it's done, it's done for good. Next, I started designing my pass design and writing its generation script.
Initially, I tried creating this model directly from scratch all programmatically. This was not the way to create passes for this use case. Unfortunately, I learned this only after wasting a lot of time. Generating passes from scratch can hinder things from a design perspective and additionally may cause performance issues under sufficient load, as with this method all pass data is generated at runtime; in this case, every API request.
Instead, use the PassKit Visual Designer, created by the creator of the corresponding passkit-generator package.
Once I had created a model using the visual designer and connected it to a script, the next step was to connect to a database and dynamically generate user information at runtime. I decided to use MongoDB, connecting directly using their TypeScript library.
Following building the database and its subsequent connection, the next step was authentication. This was a big hurdle for me, and it was not something I had ever created before. Initially, I looked at IDaaS providers such as Auth0, Okta, and AWS Cognito. I quickly realized that these would be expensive, and none fully supported my exact use case without heavy modification. I figured that building my own authentication system would be cheaper to run and much easier to get running. I was right; I had a service that was generating JWTs and saving users and their roles to the database within a few hours.
Once I had my user system, my back-end was almost ready. The only thing left was combining the generation and user APIs; both were initially separate during development. I wrote the entire API in TypeScript, which involved a small re-write of the authentication system. Finally, following this, my back-end API was complete!
The next step was creating a React Application to guide users through the login, registration, and generation flows. The UI was relatively basic, but I got it working within a week, and my application was ready. I used Material UI for assistance with some of the components.
My application was a success, and it was well-received in my school community, to which I released it. My CS teacher and IT department were very helpful and cooperative when I needed it. Since their current POS system is relatively outdated, hardware modifications were required to allow the scanning of Digital 2D barcodes, namely a new barcode scanner. The IT department worked through issues with me and was very patient yet determined during the debugging process.
I may revisit this application in the future, possibly adding support for Android devices using the Google Wallet API. I learned a lot from this application and its development, especially regarding TypeScript, generating full APIs, and authentication.
You can read more about this project on my school's blog here, please keep in mind that this write-up is much more high-level, and was published in the early stage of development.