{"id":17651792,"url":"https://github.com/diegovictor/gobarber-api","last_synced_at":"2025-07-11T13:06:12.999Z","repository":{"id":46881342,"uuid":"209998870","full_name":"DiegoVictor/gobarber-api","owner":"DiegoVictor","description":"API built during the Rocketseat Bootcamp #11 to serve web and app version ","archived":false,"fork":false,"pushed_at":"2025-06-17T15:00:20.000Z","size":1970,"stargazers_count":6,"open_issues_count":4,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-17T16:23:03.173Z","etag":null,"topics":["bootcamp","coverage-report","editorconfig","gobarber","gostack","javascript","jest","js","jwt","mongodb","node","nodejs","nodemon","postgres","redis","rocketseat","tests","ts","typeorm","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DiegoVictor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2019-09-21T14:26:07.000Z","updated_at":"2025-06-17T15:00:24.000Z","dependencies_parsed_at":"2024-12-26T18:28:41.734Z","dependency_job_id":"b0dd8e2c-003e-4c22-9b30-174bd5d40800","html_url":"https://github.com/DiegoVictor/gobarber-api","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/DiegoVictor/gobarber-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiegoVictor%2Fgobarber-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiegoVictor%2Fgobarber-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiegoVictor%2Fgobarber-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiegoVictor%2Fgobarber-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DiegoVictor","download_url":"https://codeload.github.com/DiegoVictor/gobarber-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiegoVictor%2Fgobarber-api/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264815766,"owners_count":23668026,"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":["bootcamp","coverage-report","editorconfig","gobarber","gostack","javascript","jest","js","jwt","mongodb","node","nodejs","nodemon","postgres","redis","rocketseat","tests","ts","typeorm","typescript"],"created_at":"2024-10-23T11:43:40.088Z","updated_at":"2025-07-11T13:06:12.993Z","avatar_url":"https://github.com/DiegoVictor.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [API] GoBarber\n[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/DiegoVictor/gobarber-api/config.yml?logo=github\u0026style=flat-square)](https://github.com/DiegoVictor/gobarber-api/actions)\n[![postgres](https://img.shields.io/badge/postgres-8.8.0-326690?style=flat-square\u0026logo=postgresql\u0026logoColor=white)](https://www.postgresql.org/)\n[![mongo](https://img.shields.io/badge/mongodb-4.10.0-13aa52?style=flat-square\u0026logo=mongodb\u0026logoColor=white)](https://www.mongodb.com/)\n[![redis](https://img.shields.io/badge/redis-4.3.1-d92b21?style=flat-square\u0026logo=redis\u0026logoColor=white)](https://redis.io/)\n[![typescript](https://img.shields.io/badge/typescript-4.8.4-3178c6?style=flat-square\u0026logo=typescript)](https://www.typescriptlang.org/)\n[![eslint](https://img.shields.io/badge/eslint-8.25.0-4b32c3?style=flat-square\u0026logo=eslint)](https://eslint.org/)\n[![airbnb-style](https://flat.badgen.net/badge/style-guide/airbnb/ff5a5f?icon=airbnb)](https://github.com/airbnb/javascript)\n[![jest](https://img.shields.io/badge/jest-29.2.0-brightgreen?style=flat-square\u0026logo=jest)](https://jestjs.io/)\n[![coverage](https://img.shields.io/codecov/c/gh/DiegoVictor/gobarber-api?logo=codecov\u0026style=flat-square)](https://codecov.io/gh/DiegoVictor/gobarber-api)\n[![MIT License](https://img.shields.io/badge/license-MIT-green?style=flat-square)](https://raw.githubusercontent.com/DiegoVictor/gobarber-api/main/LICENSE)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)\u003cbr\u003e\n[![Run in Insomnia}](https://insomnia.rest/images/run.svg)](https://insomnia.rest/run/?label=GoBarber\u0026uri=https%3A%2F%2Fraw.githubusercontent.com%2FDiegoVictor%2Fgobarber-api%2Fmaster%2FInsomnia_2024-12-10.json)\n\nResponsible for provide data to the [`web`](https://github.com/DiegoVictor/gobarber-web) and [`mobile`](https://github.com/DiegoVictor/gobarber-app) front-ends. Permit to register yourself as a provider or a customer, allows customers to see providers free days' hours availability and book with them a barber shop service and also notify by email providers when a book is created. Also the app has rate limit, uses JWT to logins and validation.\n\n## Table of Contents\n* [Installing](#installing)\n  * [Configuring](#configuring)\n    * [.env](#env)\n    * [Postgres](#postgres)\n      * [Migrations](#migrations)\n    * [MongoDB](#mongodb)\n    * [Redis](#redis)\n    * [Rate Limit (Optional)](#rate-limit)\n* [Usage](#usage)\n  * [Pagination](#pagination)\n    * [Link Header](#link-header)\n    * [X-Total-Count](#x-total-count)\n  * [Bearer Token](#bearer-token)\n  * [Routes](#routes)\n    * [Requests](#requests)\n* [Running the tests](#running-the-tests)\n  * [Coverage report](#coverage-report)\n\n# Installing\nEasy peasy lemon squeezy:\n```\n$ yarn\n```\nOr:\n```\n$ npm install\n```\n\u003e Was installed and configured the [`eslint`](https://eslint.org/) and [`prettier`](https://prettier.io/) to keep the code clean and patterned.\n\n## Configuring\nThe application use three databases: [Postgres](https://www.postgresql.org/), [MongoDB](https://www.mongodb.com/) and [Redis](https://redis.io/). For the fastest setup is recommended to use [docker-compose](https://docs.docker.com/compose/), you just need to up all services:\n```\n$ docker-compose up -d\n```\n\n### .env\nIn this file you may configure your Postgres, MongoDB and Redis database connection, JWT settings, email and storage driver and app's urls. Rename the `.env.example` in the root directory to `.env` then just update with your settings.\n\n|key|description|default\n|---|---|---\n|APP_API_URL|Used to mount avatars' urls.|`http://127.0.0.1:3333`\n|APP_WEB_URL|Used to create the reset password link (front-end) sent in the recover password email.|`http://127.0.0.1:3000`\n|APP_SECRET|A alphanumeric random string. Used to create signed tokens.| -\n|MAIL_DRIVER|Indicate what email service use to send messages, the possible values are `ethereal` and `ses`, to use the [SES](https://aws.amazon.com/ses/) service remember to to configure the `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` and `AWS_DEFAULT_REGION` keys.|`ethereal`\n|AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY|These keys are necessary to AWS allow the application to use the S3 and SES services throught API. See how to get yours keys here: [Set up AWS Credentials](https://docs.aws.amazon.com/toolkit-for-eclipse/v1/user-guide/setup-credentials.html)| -\n|AWS_DEFAULT_REGION|You can see your default region in the navigation bar at the top right after login in the [AWS Management Console](https://sa-east-1.console.aws.amazon.com/console/home). Read [AWS service endpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html) to know more about regions.| -\n|AWS_S3_BUCKET_NAME|Amazon S3 stores data as objects within buckets. To create a bucket see [Creating a bucket](https://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html)|gobarber\n|POSTGRES_HOST| Postgres host.|`pg`\n|POSTGRES_PORT| Postgres port.|`5432`\n|POSTGRES_USERNAME| Postgres user.|`postgres`\n|POSTGRES_PASSWORD| Postgres password.| -\n|POSTGRES_DATABASE| Application's database name.|gobarber\n|MONGO_HOST|MongoDB host.|`mongo`\n|MONGO_PORT|MongoDB port.|`27017`\n|MONGO_DATABASE|MongoDB database name.|gobarber\n|REDIS_HOST|Redis host.|`redis`\n|REDIS_PORT|Redis port.|`6379`\n|REDIS_PASSWORD|Redis password.| -\n|STORAGE_DRIVER|Indicate where the users's avatar will be stored, the possible values are `disk` and `s3`, to store into [S3](https://aws.amazon.com/s3/) remember to configure all the `AWS_*` keys.|`disk`\n\n### Postgres\nResponsible to store almost all application data. If for any reason you would like to create a Postgres container instead of use `docker-compose`, you can do it by running the following command:\n```\n$ docker run --name gobarber-postgres -e POSTGRES_PASSWORD=docker -p 5432:5432 -d postgres\n```\n\n#### Migrations\nRemember to run the database migrations:\n```\n$ yarn ts-node-dev ./node_modules/typeorm/cli.js migration:run\n```\nOr:\n```\n$ yarn typeorm migration:run\n```\n\u003e See more information on [TypeORM Migrations](https://typeorm.io/#/migrations).\n\n### MongoDB\nStore application's notifications. If for any reason you would like to create a MongoDB container instead of use `docker-compose`, you can do it by running the following command:\n```\n$ docker run --name gobarber-mongo -d -p 27017:27017 mongo\n```\n\n### Redis\nResponsible to store data utilized by the rate limit middleware and the application's cache. If for any reason you would like to create a MongoDB container instead of use `docker-compose`, you can do it by running the following command:\n```\n$ docker run --name gobarber-redis -d -p 6379:6379 redis:alpine\n```\n\n### Rate Limit (Optional)\nThe project comes pre-configured, but you can adjust it as your needs.\n\n* `src/config/rate_limit.ts`\n\n|key|description|default\n|---|---|---\n|duration|Number of seconds before consumed points are reset.|`300`\n|points|Maximum number of points can be consumed over duration.|`10`\n\n\u003e The lib [`rate-limiter-flexible`](https://github.com/animir/node-rate-limiter-flexible) was used to rate the api's limits, for more configuration information go to [Options](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#options) page.\n\n# Usage\nTo start up the app run:\n```\n$ yarn dev:server\n```\nOr:\n```\nnpm run dev:server\n```\n\n## Pagination\nAll the routes with pagination returns 30 records per page, to navigate to other pages just send the `page` query parameter with the number of the page.\n\n* To get the third page of providers:\n```\nGET http://localhost:3333/providers?page=3\n```\n\n### Link Header\nAlso in the headers of every route with pagination the `Link` header is returned with links to `first`, `last`, `next` and `prev` (previous) page.\n```\n\u003chttp://localhost:3333/providers?page=7\u003e; rel=\"last\",\n\u003chttp://localhost:3333/providers?page=4\u003e; rel=\"next\",\n\u003chttp://localhost:3333/providers?page=1\u003e; rel=\"first\",\n\u003chttp://localhost:3333/providers?page=2\u003e; rel=\"prev\"\n```\n\u003e See more about this header in this MDN doc: [Link - HTTP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link).\n\n### X-Total-Count\nAnother header returned in routes with pagination, this bring the total records amount.\n\n## Bearer Token\nA few routes expect a Bearer Token in an `Authorization` header.\n\u003e You can see these routes in the [routes](#routes) section.\n```\nPOST http://localhost:3333/appointments Authorization: Bearer \u003ctoken\u003e\n```\n\u003e To achieve this token you just need authenticate through the `/sessions` route and it will return the `token` key with a valid Bearer Token.\n\n## Routes\n|route|HTTP Method|pagination|params|description|auth method\n|:---|:---:|:---:|:---:|:---:|:---:\n|`/sessions`|POST|:x:|Body with user's email and password.|Authenticates user, return a Bearer Token and user's id and email.|:x:\n|`/users`|POST|:x:|Body with user's email and password.|Create new users.|:x:\n|`/profile`|GET|:x:| - |Logged in user profile.|Bearer\n|`/profile`|PUT|:x:|Body with user `name`, `email`, `old_password`, `password` and `password_confirmation`.|Update user.|Bearer\n|`/users/avatar`|PATCH|:x:|Multipart payload with a `avatar` field with a image (See insomnia file for good example).|Update user avatar.|Bearer\n|`/appointments`|POST|:x:|Body with appointment `provider_id` and `date`.|Create a new appointment.|Bearer\n|`/appointments/schedule`|GET|:x:|`day`, `month` and `year` query parameters.|Return user's scheduled appointments in a specific date.|Bearer\n|`/providers`|GET|:heavy_check_mark:|`page` query parameter.|Lists providers.|Bearer\n|`/providers/:id/month_availability`|GET|:x:|`month` and `year` query parameters.|List month's days availability|Bearer\n|`/providers/:id/day_availability`|GET|:x:|`day`, `month` and `year` query parameters.|List a specific day availability.|Bearer\n|`/password/forgot`|POST|:x:|Body with user's `email`.|Send to user the reset password email.|:x:\n|`/password/reset`|POST|:x:|Body with user's new `password` and `password_confirmation`.|Reset user's password.|:x:\n\n\u003e Routes with `Bearer` as auth method expect an `Authorization` header. See [Bearer Token](#bearer-token) section for more information.\n\n### Requests\n* `POST /session`\n\nRequest body:\n```json\n{\n  \"email\": \"johndoe@example.com\",\n  \"password\": \"123456\"\n}\n```\n\n* `POST /users`\n\nRequest body:\n```json\n{\n  \"name\": \"John Doe\",\n  \"email\": \"johndoe@example.com\",\n  \"password\": \"123456\"\n}\n```\n\n* `PUT /profile`\n\nRequest body:\n```json\n{\n  \"name\": \"John Doe\",\n  \"email\": \"johndoe@example.com\",\n  \"old_password\": \"123456\",\n  \"password\": \"123456789\",\n  \"password_confirmation\": \"123456789\"\n}\n```\n\n* `PATCH /users/avatar`\n\nImage file\n\n* `POST /appointments`\n\nRequest body:\n```json\n{\n  \"provider_id\": \"01931fee-32d4-4af7-b4e9-12159c5d703e\",\n  \"date\": \"2020-11-20 15:00:00\"\n}\n```\n\n* `POST /password/forgot`\n\nRequest body:\n```json\n{\n  \"email\": \"johndoe@example.com\"\n}\n```\n\n* `POST /password/reset`\n\nRequest body:\n```json\n{\n  \"password\": \"123456\",\n  \"password_confirmation\": \"123456\",\n  \"token\": \"6878f9b2-eb7c-4ad6-ac72-66d958f117c2\"\n}\n```\n\n# Running the tests\n[Jest](https://jestjs.io/) was the choice to test the app, to run:\n```\n$ yarn test\n```\nOr:\n```\n$ npm run test\n```\n\n## Coverage report\nYou can see the coverage report inside `test/coverage`. They are automatically created after the tests run.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiegovictor%2Fgobarber-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdiegovictor%2Fgobarber-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiegovictor%2Fgobarber-api/lists"}