Lynkit is basically a URL Shortner, so the most important part of this web app is to create short links for larger ones
.
To achieve this, we can adapt 2 one of 2 methods :
- Hash the Original Link directly.
- Create a
short UID
for each link.
I decided to go for the short UID
method simply for the fact that hashes can be long and it will destroy the main functionality of the app.
Important
I have plans to implement caching in the future, so I added a Click Count
field in the Lynk Document
.
I designed the Lynk Schema to hold important information :
- The User ID of the user who create it.
- The Original Link to redirect from the Link
- Short URL to match the Slug of the URL
- Click Count for caching and analytics
For creating the short version of the link, I decided to use the Nanoid library in NPM to create Unique, Short IDs for each URL entry.
NanoID provides an Async NanoID generator and an option to provide the length of the ID we need.
- Install the
nanoid
library from using the following command :
$ npm install nanoid@^3.0.0
- Create a new file in the
src/utils
folder called :shortUrl.ts
- Add the following code :
import { CustomError } from "../models/custom-error.model";
import {nanoid} from "nanoid/async"
export const shortUrlGenerator = async (size: number = 7): Promise<string> => {
try {
const shortUrl = await nanoid(size);
return shortUrl;
} catch (error) {
console.log(error);
throw new CustomError(
"Error creating Short URL",
500,
"Server Error",
null
);
}
};
Note 📌 : The line :
size : number = 7
specifies that the function takes in a size argument of type number with default value 7 if not passed
If you don't understand the line throw new CustomError()
, check out my previous blog here : Custom Error 🚨 Handler
Now, that our model and the utility function is ready, we need to create a file to handle the requests.
-
Inside the
src/controllers
folder create a new file called :lynk.ts
-
For now, we will add 2 controller functions :
- create // this adds a new link - getUserLinks // gets all the lynks created by the logged in user
The Create Function is used to add a new Lynk document. It works in 3 steps :
const {email, _id, name} = req.user; const user = await (await UserModel.findById(_id, {authentication : false})).toJSON(); if(!user){ throw new CustomError(`User does not exist`,403,'Credential Error'); }
const {link} = req.body; const shortLynk = await shortUrlGenerator(7);
const lynk = new LynkModel({
userId : user._id,
shortLynk,
originalLynk : link,
});
const savedLynk = await lynk.save();
Now that the controller is created, add the routes to create a new Lynk. Follow the previous blogs to create a new router file and a new router object with the controllers.
The complete code :
![NOTE] I have added the
jwtHandler
middleware above to extract theuser
info from theJWT Token
. You can also read about this the previous blogs.
Now, we will move to the front end of the application.