The creation of Spawner
Tags: webdev, node, javascript, react
Published: 2022-01-24 17:33:11

## Introduction
The first time I started with Web Development, HTML was easy, CSS was still googleable, and JavaScript was logical. Still, the backend was tough to understand, I wanted to create stuff, but it was difficult creating those particular models and setting up those CRUD APIs.
That has been the case with everyone who's a beginner in the backend. And also, the people who want to work in the frontend, React, React native, or any other front-end framework have to use dummy APIs or create and use data from local .json files.

Well, without further ado, I present to you, **The Spawner**.

The Spawner is the first web app that can generate a complete backend in seconds. The user only needs to be concerned with what they want to create, just the fundamental relations.
This is one of my best projects to date, and I have loved working on this. I realized this craziness when I generated a backend application using my phone in 30 seconds, laying in my bed at 1 AM yesterday.

## Important Links
1. [Github Repo](https://github.com/duttrohan0302/spawner) - Go to the repo for detailed instructions on how to give inputs
2. [Live Link](https://the-spawner.herokuapp.com/) - Do checkout the web app
3. [Postman Collections](https://www.getpostman.com/collections/a9210bc1c2ab1579d6c7)
4. [Demo Link] (https://drive.google.com/file/d/1hUqfzG2XY0Kfmu19t1Hi9pfQQHZxzFKj/view?usp=sharing) - A video explaining the use case of the app
5. [LinkedIn Post](https://www.linkedin.com/posts/rohandutt0302_projects-backend-generalization-activity-6891437675933519873-3guA)

## Functionality
Let's try to understand the functionality with the help of an example. 
Say we want to create the backend for an app which can have 3 types of Models, users(having basic details), state(having the state name) and finally district(having the state Id and the district name). That's all we need to provide to our Spawner app, we can use the UI(built in React) or we can hit a simple POST request with the data using Postman.

### If you want The Spawner UI
Go to the [Homepage](https://the-spawner.herokuapp.com/) and fill the entries as required
![Spawner entries](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dohkigwksirh068zlx1m.png)
OR
### If you're using Postman

Send a POST request to 
https://the-spawner.herokuapp.com/app
with the following JSON object(or according to your needs, the format should be the same) as the body
```
{
    "name": "Show Case",
    "email": "showcase@gmail.com",
    "slug": "showcase-app",
    "password": "123456",
    "schema": [
        {
            "name": "user",
            "isAuth": true,
            "attributes": [
                {
                    "name": "name",
                    "type": "String",
                    "required": true
                },
                {
                    "name": "email",
                    "type": "String",
                    "required": true
                },
                {
                    "name": "password",
                    "type": "String",
                    "required": true
                }
            ]
        },
        {
            "name": "state",
            "attributes": [
                {
                    "name": "name",
                    "type": "String",
                    "required": true
                }
            ]
        },
        {
            "name": "district",
            "attributes": [
                {
                    "name": "name",
                    "type": "String",
                    "required": true
                },
                {
                    "name": "state_id",
                    "type": "ObjectId",
                    "required": false
                }
            ]
        }
    ]
}
```
Then fire up your browser and go to https://the-spawner.herokuapp.com/zips/yourAppSlug.zip to download the zipped backend app.
`Voila` your app is generated.

![Backend App](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gevg5uo0baiwzy2m6mok.png)
It's all set with Mongoose, Express and NodeJS, all you need to do is just set the env parameters and run using npm start.


## Technical Jargon
I have utilized the template literals to their fullest in this web application. 
Tech Used - NodeJS, ReactJS, Express, Mongoose, JWT, Passport, BcryptJS

To generate any backend app, a few things had to be kept in mind-
1. Creating the models - I utilized the schema given by the user to transform it into mongoose models
2. Creating a folder structure which could work easily and be understandable to a majority of population (`fs-extra` helped a lot in quickly creating directories and files)
![Folder Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5qu30h7qtd1ez7s4b16t.png)
3. Generating all the possibilities of CRUD Routes in minimum number of Routes, for e.g. for a GET route, user can given `/model/all` to get all instances of that model or `/model/10/?findBy=name&value=rohan` to get 10 model instances having the property name equals to rohan
4. Generating a README automatically for every backend app with all the routes data - I accomplished this using template literals and jotting down a good standard README
5. Generating the base files like index.js, .env, config, middlewares(if required), and data for routes, controllers and services - again template literals came to rescue

### Extra Checks
1. Checking if any attribute has the type `ObjectId`, if so, check the `ref` provided, it will tell us the connection between models and generate the `Model.js` file accordingly 
2. Checking if any attribute has the type `Array`, if so, check the `ref`, if ref exists, the attribute will be an `Array` of `ObjectId`, if not, it will be an `Array` of `String
3. To make sure I get the expanded versions of all the `ObjectId`, I have used the `mongoose-autopopulate` package
4. Check if `isAuth=true?` for any model, if yes, additional encryption using `BcryptJS` and JWT token setup(using `Json Web Token` and `PassportJS`) is to be done for that particular model. In this case, there must be a `password` attribute in that model.
5. Mongoose automatically pluralizes our model names, which is fine when we're creating the backend ourselves but in automatic backend generation, it's important that the model name stays exactly the same to ensure that we are able to query database and use populate easily.
6. Formatting the `.js` and `.json` files created. The template literals creates the files but the format is complete chaos, to solve that problem, I have used `js-beautify` package to format the backend app files using a custom formatter.


## Current Ongoing Improvements
1. Adding Validations to the Schema Input, to make sure proper formatted data is being sent to the backend
2. UI Improvements obviously ;)

## Limitations
Or as I like to call them, scope for future work
1. Infinite loop possibility due to mongoose auto-populate - As we are using auto-populate, any one can create relations in such a way that it can get stuck in an infinite loop, I need to set depth of populate according to the relations
2. Add validations in the generated backend apps automatically, I am sure validator package can help in this
3. Check uniqueness of entries like email or username in the generated backend apps automatically
4. If I have an attribute with the type Array, it will be easy to create an instance of that model in your app but updating it is a whole other story, currently, to update it, we have to send the updated array(old items +/- changes) to update it. A method should be created so that even if I just supply the new item, it's appended(or removed) to/from that array.
5. Options for file uploads in the generated backend app using aws s3 and multer

## My Socials
1. [My Portfolio](https://duttrohan0302.github.io/portfolio/)
2. [Github Profile](https://github.com/duttrohan0302)
3. [LinkedIn Profile](https://linkedin.com/in/rohandutt0302)
4. [Instagram](https://instagram.com/duttrohan3107)