Snipit is a URL Shortener API. Snipit allows you shorten long URLs, customize links, and generate qrcode for shortned links. This API was built by Chinwendu Enyinna using JavaScript-based server side technologies. This API follows the REST architectural design pattern.
The following are the requirements I implemented in this project π:
-
Users should be able to sign up(register) and sign in into their account
-
For the URL Shortener functionality, users should be able to:
-
Shorten a long url
-
Customize their short url using a custom name. This is particularly beneficial for small SMEs as it helps promote their brand.
-
Generate QRCodes for their shortened URLS. Users can download the QR code image and use it in their promotional materials or/and on their website.
-
Track their shortened URL's performance
-
See the history of links theyβve created so they can easily find and reuse links they have previously created.
-
git clone https://github.com/wendeee/scissor.git
npm install
Update .env with example.env
- Sign up on Cloudinary to get API_KEY for free and other details needed in your .env file
- To implement forgot password and reset password functionality, I used Nodemailer and mail trap to send reset token to user's email.
npm run dev
field | data_type | constraints |
---|---|---|
name | string | required |
string | required | |
password | string | required |
confirmPassword | string | required |
confirmationCode | string | added dynamically |
provider | string | added dynamically |
field | data_type | constraints |
---|---|---|
longURL | string | required |
shortURL | string | added dynamically |
createdBy | string | referenced |
UrlCode | string | added dynamically |
customName | string | added dynamically |
clicks | number | updated dynamically |
qrcodeurl | string | addedynamically |
clickHistory | sring Array | required |
field | data_type | constraints |
---|---|---|
string | required | |
generatedFor | string(uuid) | referenced |
otp | string | required |
createdAt | Date | required |
expiresAt | Date | required |
-
Route: /api/v1/auth/signup
-
method: POST
-
π: Body
{
"name": "Jackson",
"email": "jackson@gmail.com",
"password": "jackson12345",
"confirmPassword": "jackson12345"
}
π: Response
{
"data": {
"modifiedResponse": {
"id": "d983edfc-31d7-47f3-971f-bc3ec6fbd1d5",
"provider": "email",
"status": "Pending",
"name": "Jackson",
"email": "jackson@gmail.com",
"confirmationCode": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6eyJlbWFpbCI6ImRldmJhYnl3ZW5kZWVlQGdtYWlsLmNvbSJ9LCJpYXQiOjE2ODgxMDQ5MjIsImV4cCI6MTY4ODEwODUyMn0.6Nc_evPpN9eW75PTzfd29CUth3RADHZpo470jkPuCxA",
"updatedAt": "2023-06-30T06:02:02.019Z",
"createdAt": "2023-06-30T06:02:02.019Z"
}
},
"status": 200,
"message": [
{
"type": "success",
"content": "User has been successfully registered. Please confirm your email."
}
]
}
Route: /api/auth/login method: POST
π: Body
{
"email": "jackson@gmail.com",
"password": "jackson12345"
}
π: Response
{
"data": {
"modifiedResponse": {
"id": "d983edfc-31d7-47f3-971f-bc3ec6fbd1d5",
"name": "Jackson",
"email": "jackson@gmail.com",
"provider": "email",
"status": "Pending",
"confirmationCode": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6eyJlbWFpbCI6ImRldmJhYnl3ZW5kZWVlQGdtYWlsLmNvbSJ9LCJpYXQiOjE2ODgxMDQ5MjIsImV4cCI6MTY4ODEwODUyMn0.6Nc_evPpN9eW75PTzfd29CUth3RADHZpo470jkPuCxA",
"createdAt": "2023-06-30T06:02:02.019Z",
"updatedAt": "2023-06-30T06:02:02.019Z"
},
"jwtToken": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImQ5ODNlZGZjLTMxZDctNDdmMy05NzFmLWJjM2VjNmZiZDFkNSIsImlhdCI6MTY4ODEwNTAwOCwiZXhwIjoxNjg4MTA4NjA4fQ.2qrIJhJmm9PtZjrvSTDS0PRzmvzP_O5MlAq0G38ng6k"
}
},
"status": 200,
"message": []
}
- Route: /api/v1/auth/forgotPassword
- Method: POST
π: Body
{
"email": "jackson@gmail.com"
}
π: Response
{
"status": "success",
"message": "An OTP token has been sent to your email"
}
- Route: api/v1/url
- Method: POST
- Header
- Authorization: Bearer {token}
π: Body
{
"longURL": "https://www.amazon.com/Too-Late-Definitive-Colleen-Hoover/dp/1538756595/ref=zg_bs_g_books_sccl_1/139-5024682-0087834?psc=1",
"customName": "book"
}
π: Response
{
"data": {
"customUrl": {
"id": "94f85561-c46d-457a-8b0d-e5b2654871f3",
"clicks": 0,
"longURL": "https://www.amazon.com/Too-Late-Definitive-Colleen-Hoover/dp/1538756595/ref=zg_bs_g_books_sccl_1/139-5024682-0087834?psc=1",
"shortURL": "https://snipit.onrender.com/book",
"UrlCode": "book",
"createdBy": "3dabcdc5-eb77-4198-874e-f597d1153908",
"clickHistory": [],
"updatedAt": "2023-07-03T09:13:47.086Z",
"createdAt": "2023-07-03T09:13:47.086Z",
"customName": null,
"qrcodeurl": null
}
},
"status": 200,
"message": [
{
"type": "success",
"content": "Short URL created!"
}
]
}
//Shortening a URL without a custom name
{
"data": {
"customUrl": {
"id": "80c6cc7e-7080-4e30-afed-7841371db20c",
"clicks": 0,
"longURL": "https://www.amazon.com/Atomic-Habits-Proven-Build-Break/dp/0735211299/ref=zg_bs_g_books_sccl_4/139-5024682-0087834?psc=1",
"shortURL": "https://snipit.onrender.com/_JKNjM",
"UrlCode": "_JKNjM",
"createdBy": "3dabcdc5-eb77-4198-874e-f597d1153908",
"clickHistory": [],
"updatedAt": "2023-07-03T09:19:44.194Z",
"createdAt": "2023-07-03T09:19:44.194Z",
"customName": null,
"qrcodeurl": null
}
},
"status": 200,
"message": [
{
"type": "success",
"content": "Short URL created!"
}
]
}
//shortening a URL that has already been cached
{
"data": {
"customUrl": "https://snipit.onrender.com/_JKNjM"
},
"status": 200,
"message": [
{
"type": "success",
"content": "ShortUrl generated successfully!!"
}
]
}
- Route: /api/v1/url/qrcode
- Method: POST
- Header
- Authorization: Bearer {token}
π: Body
{
"shortURL": "https://snipit.onrender.com/_JKNjM"
}
π: Response
{
"data": {
"url": "https://snipit.onrender.com/_JKNjM",
"qrCodeImageUrl": "https://res.cloudinary.com/dwsbmjhzd/image/upload/v1688376327/qrcodes/dxtapjl1ptuigkfn0jil.png"
},
"status": 200,
"message": [
{
"type": "success",
"content": "QRCode generated!"
}
]
}
- Route: /api/v1/url/history
- Method: GET
- Header
- Authorization: Bearer {token}
π: Response
{
"data": {
"generatedShortUrl": [
{
"shortURL": "https://snipit.onrender.com/_JKNjM",
"longURL": "https://www.amazon.com/Atomic-Habits-Proven-Build-Break/dp/0735211299/ref=zg_bs_g_books_sccl_4/139-5024682-0087834?psc=1",
"numberOfClicksOnShortUrl": 1,
"clickLocation": [
{
"location": "Oregon, United States",
"timestamp": "2023-07-03T09:29:24.118Z"
}
],
"id": "80c6cc7e-7080-4e30-afed-7841371db20c",
"qrcodeurl": "https://res.cloudinary.com/dwsbmjhzd/image/upload/v1688376327/qrcodes/dxtapjl1ptuigkfn0jil.png",
"clicks": 1,
"createdat": "2023-07-03T09:19:44.194Z"
},
{
"shortURL": "https://snipit.onrender.com/book",
"longURL": "https://www.amazon.com/Too-Late-Definitive-Colleen-Hoover/dp/1538756595/ref=zg_bs_g_books_sccl_1/139-5024682-0087834?psc=1",
"numberOfClicksOnShortUrl": 0,
"clickLocation": [],
"id": "94f85561-c46d-457a-8b0d-e5b2654871f3",
"qrcodeurl": null,
"clicks": 0,
"createdat": "2023-07-03T09:13:47.086Z"
},
{
"shortURL": "https://snipit.onrender.com/ZIvwUi",
"longURL": "https://www.amazon.com/Atomic-Habits-Proven-Build-Break/dp/0735211299/ref=zg_bs_g_books_sccl_4/139-5024682-0087834?psc=1",
"numberOfClicksOnShortUrl": 0,
"clickLocation": [],
"id": "6e6679d5-05a2-430e-8275-a0373039f7ef",
"qrcodeurl": null,
"clicks": 0,
"createdat": "2023-07-03T09:22:02.399Z"
}
],
"shortUrlCount": 3,
"QRCodeCount": 1
},
"status": 200,
"message": [
{
"type": "success",
"content": "URL history retrieved!"
}
]
}
- Writing Nodejs with Typescript
- Working with Postgresql
-
Twitter - @_ChinwenduE
-
Email - chinwe.promise2016@gmail.com
Project Link: https://github.com/wendeee/scissor