{"id":18418901,"url":"https://github.com/trobert42/api_justifytext","last_synced_at":"2026-04-11T00:06:13.766Z","repository":{"id":226270987,"uuid":"768125696","full_name":"trobert42/API_JustifyText","owner":"trobert42","description":"A simple REST API on Node.JS that justifies a text passed as a parameter","archived":false,"fork":false,"pushed_at":"2024-03-14T14:07:51.000Z","size":9890,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-13T06:11:37.941Z","etag":null,"topics":["api-rest","aws","docker-compose","jwt-token","nodejs","postgresql"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/trobert42.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-06T14:14:25.000Z","updated_at":"2024-03-10T18:51:15.000Z","dependencies_parsed_at":"2024-12-24T17:37:04.862Z","dependency_job_id":null,"html_url":"https://github.com/trobert42/API_JustifyText","commit_stats":null,"previous_names":["trobert42/api_justifytext"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trobert42%2FAPI_JustifyText","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trobert42%2FAPI_JustifyText/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trobert42%2FAPI_JustifyText/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trobert42%2FAPI_JustifyText/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/trobert42","download_url":"https://codeload.github.com/trobert42/API_JustifyText/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248670434,"owners_count":21142904,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-rest","aws","docker-compose","jwt-token","nodejs","postgresql"],"created_at":"2024-11-06T04:14:55.631Z","updated_at":"2025-12-30T23:05:04.681Z","avatar_url":"https://github.com/trobert42.png","language":"TypeScript","readme":"# API_JustifyText\nA simple REST API on Node.JS that justifies a text passed as a parameter.\n\n# Project Description\nThis app implements a REST API using Node.JS/Typescript, it consists of two endpoints: /api/token and /api/justify.\nTo obtain access to the /api/justify endpoint, a token must be acquired by sending a POST request to /api/token with a JSON body containing the email address. Once authenticated, sending a POST request with text content to /api/justify will return the justified text. The justification algorithm is custom-built.\nAny other routes will give you an 404 Not Found error. \n\nA daily rate limit of 80,000 words is enforced, and the length of each justified text line is limited to 80 characters.\n\nThe app covers aspects such as authentication, algorithm implementation, string manipulation, Node.js environment setup (including routes, controllers, and middlewares), database management, error handling, deployment of the API, and Dockerization.\n\n\n![NodeJS](https://img.shields.io/badge/node.js-6DA55F?style=for-the-badge\u0026logo=node.js\u0026logoColor=white)\n![Express.js](https://img.shields.io/badge/express.js-%23404d59.svg?style=for-the-badge\u0026logo=express\u0026logoColor=%2361DAFB)\n![Postgres](https://img.shields.io/badge/postgres-%23316192.svg?style=for-the-badge\u0026logo=postgresql\u0026logoColor=white)\n![Docker](https://img.shields.io/badge/docker-%230db7ed.svg?style=for-the-badge\u0026logo=docker\u0026logoColor=white)\n![JWT](https://img.shields.io/badge/JWT-black?style=for-the-badge\u0026logo=JSON%20web%20tokens)\n![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge\u0026logo=github\u0026logoColor=white)\n![Jest](https://img.shields.io/badge/-jest-%23C21325?style=for-the-badge\u0026logo=jest\u0026logoColor=white)\n![AWS](https://img.shields.io/badge/AWS-%23FF9900.svg?style=for-the-badge\u0026logo=amazon-aws\u0026logoColor=white)\n\n\n## Structure\nHere's the structure of the project directory\n```\nAPI_JustifyText/\n├── docker-compose.yml\n├── .env\n├── README.md\n└── api/\n    ├── src/\n    │   ├── controllers/\n    │   ├── db/\n    │   ├── middleware/\n    │   ├── models/\n    │   ├── routes/\n    │   ├── utils/\n    │   └── server.ts\n    ├── tests/\n    ├── Dockerfile\n    ├── package.json\n    ├── package-lock.json\n    ├── tsconfig.json\n    └── jest.config.js\n```\n\n\n# Usage \nTo use this API, you can follow these steps:\n1. Obtain a unique Token by sending a POST request to `http://16.171.206.86:3000/api/token` with a JSON body:\n   ``` bash\n   curl --request POST \\\n    --url 'http://16.171.206.86:3000/api/token/?email=test%40example.com' \\\n    --header 'Content-Type: application/json' \\\n    --data '{ \"email\":\"test@example.com\" }'\n   ```\n2. Make a POST request with the header \"Authorization\" and with the value \"Bearer ${YOUR_TOKEN}\" to `http://16.171.206.86:3000/api/justify` with a plain/text body as Content-Type for getting your text justified. Here's the cURL command:\n   ``` bash\n   curl -X POST \\\n   -H \"Authorization: Bearer YOUR_TOKEN\" \\\n   -H \"Content-Type: text/plain\" \\\n   -d \"YOU VERY LONG TEXT YOU WANT TO BE JUSTIFIED\" \\\n   http://16.171.206.86:3000/api/justify\n   ```\n   \nI recommend to use [Insomnia](https://insomnia.rest/) and a generator of text like [lipsum](https://www.lipsum.com/) for making requests, it's easier, especially for including text content in the request body and to look at the output. It also memorizes the URL and the all the headers values.\n\n# How run locally the project \n## Prerequisites\nYou'll need to have docker-compose, please refer to the [official Docker documentation](https://docs.docker.com/compose/install/) to install it.\n\n## Installation\nIf you want to run locally this project on your computer, you can clone this repo:\n1. Clone the repo\n  ``` bash\n  git clone https://github.com/trobert42/API_JustifyText.git\n  cd API_JustifyText/\n  ```\n2. Set the environment .env\n  ``` bash\n  POSTGRES_USER='your_username'\n  POSTGRES_PASSWORD='your_pwd'\n  JWT_SECRET='your_secret'\n  ```\n3. Change the variables as you desire\n```\nconst wordsLimitPerDay = 80000;\nconst lineLenLimit = 80;\n```\n4. Build and run the containers with docker-compose\n  ``` bash\n  docker-compose up --build -d # \"-d\" flag stands for \"detached\" mode, it starts the services in the background\n  docker-compose logs -f # \"-f\" stands for \"follow\", it allows you to continuously see and follow the output of the logs from the container\n  ```\nSome helpful commands to stop containers and clean volumes\n``` bash\n docker-compose -f docker-compose.yml down -v #watch out, it cleans the entire database\n docker system prune -a -f --volumes\n```\n\n# 💬 Notes\n## Difficulties\nWhat was really challenging is for me to apply the right methods to handle the whole project. My formation is based on self-taught so every informations come from forums, videos, articles on the internet. Sometimes, some informations are pretty old or deprecated because tools are updated meanwhile or there are just better ones today. \n\nI used Nest.Js before and this framework is a bit different for the structure project process compared to this one. But i manage to find some logic on how i should structure the folders/files and keep it simple. \n\nOne thing that was unknown to me is the sql environment, i used Prisma as a ORM before and for this little assessment, with no use of ORM tools, i had to look for sql commands to access values in my db. Thankfully, i just needed to retrieve data or updates some of it, so nothing really complex.\n\nI find the justifyText algorithm very vague. Even on these online websites that justifies your text, it does not give everytime the same output. At first i had a problem with the ‘\\n’ character because i didn't manage it. I realized a working algorithm but i know there are better and optimal ways to do it.\n\nAn another thing i don’t have are the good practices for the commits and git managing. I dont know when i have to commit or how i should write my message so its professional.\n\n## What was easier\nFor the final project of my web school common core, I focused on authentication and API integration, so this task didn't feel new to me. I was already familiar with the Backend/Docker environment, and there's a lot of documentation available.\n\nI enjoyed working on this small project, although I did spend a bit too much time on the text justification algorithm. Nonetheless, I was able to learn more about AWS and unit testing, which are new technologies to me. \n\n## Particularities of the projet\nThis assessment serves as an exercise, and it is acknowledged that some aspects of the project may lack practical relevance or context.\n\nThere is one unique token which is given by the endpoint /api/token. If you lose it, you won't be able to receive it again and you can't use the same email because credentials will be taken.\n\nThis token will not expire.\n\nWords are defined by spaces, so \"-\" or \"123\" are valids.\n\nEvery day at midnight, the word count is reset to zero. If you have 10 words left free, you can't put a request with body more than 10 words long.\n\n\n# Documentation\nIf you want to follow how i managed the project throrough the days, here's my [notion's page](https://sparkly-printer-981.notion.site/c7d86bf786e44e2cb2723107e43e54aa?v=9a7da235870644f7a6031717d4ab01ee\u0026pvs=4) ⬅️ about this project\n\n### Nodejs project init \n- https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment\n- https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/routes\n- https://www.youtube.com/watch?v=H9M02of22z4\n\n### Online justify text tools\n- https://onlinetexttools.com/justify-text\n- https://texttools.org/justify-text\n- https://texttools.io/justify-text\n\n### Nodejs Middleware\n- https://expressjs.com/en/guide/using-middleware.html\n- https://www.turing.com/kb/building-middleware-for-node-js\n\n### Others tools (pool, node-cron)\n- https://stackoverflow.com/questions/23271250/how-do-i-check-content-type-using-expressjs\n- https://medium.com/@amr258144/connection-pooling-in-node-js-ea4421c72dc\n- https://node-postgres.com/apis/pool\n- https://www.npmjs.com/package//node-cron\n\n### Deployment with AWS\n- https://docs.aws.amazon.com/fr_fr/iot/latest/developerguide/creating-a-virtual-thing.html\n- https://medium.com/@rajani103/deploying-nodejs-app-on-aws-ec2-instance-step-by-step-1b00f807cdce\n\n### Jest for Test\n- https://jestjs.io/docs/getting-started\n- https://dev.to/nathan_sheryak/how-to-test-a-typescript-express-api-with-jest-for-dummies-like-me-4epd\n\n# Upcoming Features\n## How to run tests with Jest\nI did not yet implemented all the tests. Stay tuned, i'll work on it.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrobert42%2Fapi_justifytext","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftrobert42%2Fapi_justifytext","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrobert42%2Fapi_justifytext/lists"}