https://github.com/joschonarth/the-movie-api
🎬 An API for managing a movie catalog, integrating with the TMDB API to fetch movie information.
https://github.com/joschonarth/the-movie-api
axios docker eslint fastify nodejs postgresql prisma swagger tmdb tmdb-api tsup typescript vitest zod
Last synced: 3 months ago
JSON representation
🎬 An API for managing a movie catalog, integrating with the TMDB API to fetch movie information.
- Host: GitHub
- URL: https://github.com/joschonarth/the-movie-api
- Owner: joschonarth
- License: mit
- Created: 2025-02-06T18:01:44.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-04-21T19:30:54.000Z (about 1 year ago)
- Last Synced: 2026-01-03T16:20:55.806Z (6 months ago)
- Topics: axios, docker, eslint, fastify, nodejs, postgresql, prisma, swagger, tmdb, tmdb-api, tsup, typescript, vitest, zod
- Language: TypeScript
- Homepage:
- Size: 739 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
🎬 The Movie API
🎬 Uma API RESTful para gerenciar um catálogo de filmes, integrada à API do The Movie Database (TMDB) para obter informações detalhadas sobre os filmes.
## 📑 Índice
- [👀 Visão Geral](#-visão-geral)
- [🛠️ Tecnologias Utilizadas](#️-tecnologias-utilizadas)
- [⚙️ Funcionalidades](#️-funcionalidades)
- [🚀 Como Executar o Projeto](#-como-executar-o-projeto)
- [📋 Pré-requisitos](#-pré-requisitos)
- [🔑 Obtenha a sua API Key do TMDB](#-obtenha-a-sua-api-key-do-tmdb)
- [🔧 Instalação](#-instalação)
- [▶️ Execução](#️-execução)
- [🐳 Rodando a aplicação com Docker](#-rodando-a-aplicação-com-docker)
- [🔒 Autenticação](#-autenticação)
- [📌 Tabela de Endpoints](#-tabela-de-endpoints)
- [🔗 Endpoints](#-endpoints)
- [📝 Documentação da API com Swagger](#-documentação-da-api-com-swagger)
- [🧪 Testes](#-testes)
- [🤝 Contribuições](#-contribuições)
- [⭐ Apoie este Projeto](#-apoie-este-projeto)
- [📜 Licença](#-licença)
- [📞 Contato](#-contato)
## 👀 Visão Geral
O **The Movie API** é uma aplicação backend desenvolvida com foco em performance, escalabilidade e organização de código. Integrando-se à poderosa base de dados da **TMDB** (The Movie Database), esta API permite que usuários gerenciem uma lista personalizada de filmes, incluindo funcionalidades como adicionar à lista de desejos, atualizar o estado (assistido, a assistir, recomendado etc.), registrar avaliações e acompanhar um histórico detalhado de ações. Além disso, a aplicação conta com autenticação básica para segurança, documentação via Swagger, testes automatizados com Vitest e uma arquitetura moderna com Fastify, TypeScript e Prisma.
## 🛠️ Tecnologias Utilizadas
- 🟢 **Node.js**: Plataforma para execução do JavaScript no servidor.
- 🟦 **TypeScript**: Superset do JavaScript com tipagem estática.
- ⚡ **Fastify**: Framework web de alta performance para Node.js.
- 🛢️ **Prisma**: ORM (Object Relational Mapper) para banco de dados.
- 🗄️ **PostgreSQL**: Banco de dados relacional utilizado para armazenar informações.
- 🐳 **Docker**: Containerização da aplicação.
- 💎 **Zod**: Validação de esquemas e dados.
- 📜 **Swagger**: Documentação automática da API.
- ✨ **Axios**: Cliente HTTP para fazer requisições à API do TMDB.
- ⚙️ **ESLint**: Linter para garantir a qualidade do código.
- 🧪 **Vitest**: Framework de testes.
- 🔨 **Tsup**: Ferramenta para bundling.
## ⚙️ Funcionalidades
- 🎥 **Adicionar filme à lista de desejos:** Adicione um filme à sua lista pessoal.
- 📄 **Listar todos os filmes:** Retorne todos os filmes presentes na sua lista, com paginação e filtros.
- 🔍 **Buscar informações de um filme específico:** Pesquise informações detalhadas sobre um filme.
- 🔄 **Atualizar o estado de um filme:** Alterar o estado de um filme (de "a assistir" para "assistido", por exemplo).
- ⭐ **Avaliar um filme:** Dê uma nota para o filme de 0 a 5.
- 📖 **Histórico de ações:** Visualize o histórico de ações relacionadas a um filme (adicionado, avaliado, etc).
- 📊 **Logs das requisições:** Visualize os logs das requisições feitas na API.
## 🚀 Como Executar o Projeto
### 📋 Pré-requisitos
- 🟩 [Node.js 20](https://nodejs.org/en/download/)
- 📦 [npm 10](https://www.npmjs.com/)
### 🔑 Obtenha a sua API Key do TMDB
Antes de acessar a aplicação, é necessário criar uma conta no **TMDB** e obter uma API Key.
1. Acesse [The Movie Database (TMDB)](https://www.themoviedb.org/) e crie uma conta.
2. Após criar a conta, vá até as [Configurações da API](https://www.themoviedb.org/settings/api) e gere sua API Key.
3. Copie essa chave e configure no arquivo `.env` da aplicação a variável `TMDB_API_KEY` (veja a seção de instalação para mais detalhes).
### 🔧 Instalação
1. **Clone o repositório:**
```bash
git clone https://github.com/joschonarth/the-movie-api.git
```
2. Acesse o diretório do projeto:
```bash
cd the-movie-api
```
3. **Instale as dependências:**
```bash
npm install
```
### ▶️ Execução
1. **Crie um arquivo `.env` a partir do exemplo:**
O projeto já contém um arquivo `.env.example` com os exemplos de variáveis de ambiente que você precisa configurar. Copie para `.env` e preencha as informações de acordo com suas necessidades.
2. **Configure o banco de dados:**
- **Com Docker**:
O projeto utiliza o **PostgreSQL** como banco de dados. Para rodar o banco de dados localmente via Docker, siga os passos abaixo:
1. No arquivo `.env`, configure a URL de conexão para o banco de dados com o seguinte valor:
```env
DATABASE_URL="postgresql://docker:docker@localhost:5432/moviedb?schema=public"
```
2. Em seguida, inicie o banco de dados utilizando a imagem `bitnami/postgresql` com o comando:
```bash
docker-compose up movie-api-pg -d
```
Esse comando irá iniciar o banco de dados em um contêiner Docker com a configuração definida no arquivo [`docker-compose.yml`](./docker-compose.yml).
- **Com PostgreSQL Local**:
Caso você tenha o PostgreSQL instalado localmente, você precisará configurar a variável de ambiente `DATABASE_URL` com os dados de conexão para o banco de dados. A URL de conexão deve ter o seguinte formato:
```env
DATABASE_URL=postgresql://:@localhost:/
```
Certifique-se de ajustar ``, ``, `` e `` de acordo com a sua configuração.
3. **Execute as migrações do banco de dados:**
```bash
npx prisma migrate dev
```
4. **Rodando a aplicação localmente:**
Para rodar a aplicação localmente, execute o seguinte comando:
```bash
npm run dev
```
A aplicação estará disponível em [http://localhost:3333](http://localhost:3333).
### 🐳 Rodando a aplicação com Docker
Este projeto está containerizado usando o **Docker**. Para rodar a aplicação em um container Docker, siga os passos abaixo:
1. Configure a URL de conexão adequada para o container Docker no arquivo `.env`:
```bash
DATABASE_URL=postgresql://docker:docker@movie-api-pg:5432/moviedb?schema=public
```
2. Realize a build do projeto com o comando:
```bash
npm run build
```
3. Em seguida, utilize o comando abaixo para subir a aplicação no Docker:
```bash
docker-compose up --build
```
A aplicação estará disponível em [http://localhost:3333](http://localhost:3333) dentro do container.
## 🔒 Autenticação
Todas as rotas da API estão protegidas por **Basic Auth**. Para autenticação, utilize as seguintes variáveis de ambiente:
```env
ADMIN_USER=admin
ADMIN_PASSWORD=admin123
```
Se estiver usando uma ferramenta como **Postman** para testar a API, siga os passos abaixo:
1. Selecione a requisição desejada.
2. Vá até a aba de **Authorization**.
3. Em **Auth Type** escolha o método **Basic Auth**.
4. Informe o usuário e senha configurados nas variáveis de ambiente.
5. Envie a requisição normalmente.
Caso esteja utilizando `cURL`, você pode passar as credenciais da seguinte forma:
```sh
curl -u admin:admin123 http://localhost:3333/movie
```
Caso esteja utilizando `httpie`, você pode passar as credenciais da seguinte forma:
```bash
http -a admin:admin123 http://localhost:3333/movie
```
## 📌 Tabela de Endpoints
| Método | Rota | Descrição |
|--------|-----------------------|---------------------------------------|
| POST | `/movie` | Adiciona um filme à lista de desejos |
| GET | `/movie` | Lista todos os filmes |
| GET | `/movie/:id` | Busca um filme específico |
| PUT | `/movie/:id/state` | Atualiza o estado do filme |
| POST | `/movie/:id/rate` | Avalia um filme |
| GET | `/movie/:id/history` | Histórico de ações do filme |
| GET | `/log` | Logs de requisições |
## 🔗 Endpoints
### 🎥 Adicionar Filme à Lista de Desejos
- **Descrição:** Adiciona um filme à lista de desejos.
- **Método**: `POST`
- **URL**: `/movie`
- **Corpo da Requisição:**
```json
{
"title": "Interstellar"
}
```
- **Exemplo de Resposta:**
```json
{
"id": "ae44ae5b-7d56-483a-8283-289c784ee91d",
"title": "Interstellar",
"synopsis": "The adventures of a group of explorers who make use of a newly discovered wormhole to surpass the limitations on human space travel and conquer the vast distances involved in an interstellar voyage.",
"releaseYear": 2014,
"genre": "Adventure, Drama, Science Fiction",
"state": "TO_WATCH",
"createdAt": "2025-04-21T13:41:58.833Z",
"rating": null
}
```
### 📄 Listar Filmes
- **Descrição:** Retorna uma lista de filmes cadastrados. Possui suporte a paginação e filtros.
- **Método**: `GET`
- **URL**: `/movie`
- **Query Params**:
- `state`: Filtra os filmes pelo estado. Pode ser "`to_watch`", "`watched`", "`rated`" "`recommended`", "`no_recommended`".
- `limit`: Define o número máximo de filmes por página. Exemplo: `limit=10`.
- `page`: Define a página de busca. Exemplo: `page=1`.
- **Exemplo de Requisição**:
```url
GET /movie?state=watched&limit=10&page=1
```
- **Exemplo de Resposta:**
```json
{
"data": [
{
"id": "ae44ae5b-7d56-483a-8283-289c784ee91d",
"title": "Interstellar",
"synopsis": "The adventures of a group of explorers who make use of a newly discovered wormhole to surpass the limitations on human space travel and conquer the vast distances involved in an interstellar voyage.",
"releaseYear": 2014,
"genre": "Adventure, Drama, Science Fiction",
"state": "WATCHED",
"rating": null,
"createdAt": "2025-02-09T19:16:02.882Z"
}
],
"pagination": {
"limit": 10,
"currentPage": 1,
"totalPages": 1,
"totalItems": 1
}
}
```
### 🔍 Buscar Filme
- **Descrição:** Busca informações detalhadas de um filme específico.
- **Método**: `GET`
- **URL**: `/movie/:id`
- **Parâmetros de URL:**
- `id`: ID do filme.
- **Exemplo de Resposta:**
```json
{
"id": "ae44ae5b-7d56-483a-8283-289c784ee91d",
"title": "Interstellar",
"synopsis": "The adventures of a group of explorers who make use of a newly discovered wormhole to surpass the limitations on human space travel and conquer the vast distances involved in an interstellar voyage.",
"releaseYear": 2014,
"genre": "Adventure, Drama, Science Fiction",
"state": "TO_WATCH",
"rating": null,
"createdAt": "2025-02-09T19:16:02.882Z"
}
```
### 🔄 Atualizar o Estado de um Filme
- **Descrição:** Atualiza o estado de um filme (ex: "a assistir" para "assistido").
- **Método**: `PUT`
- **URL**: `/movie/:id/state`
- **Parâmetros de URL:**
- `id`: ID do filme.
- **Corpo da Requisição:**
```json
{
"state": "watched"
}
```
- **Exemplo de Resposta:**
```json
{
"id": "ae44ae5b-7d56-483a-8283-289c784ee91d",
"title": "Interstellar",
"synopsis": "The adventures of a group of explorers who make use of a newly discovered wormhole to surpass the limitations on human space travel and conquer the vast distances involved in an interstellar voyage.",
"releaseYear": 2014,
"genre": "Adventure, Drama, Science Fiction",
"state": "WATCHED",
"rating": null,
"createdAt": "2025-02-09T19:16:02.882Z"
}
```
### ⭐ Avaliar um Filme
- **Descrição:** Avalia um filme de 0 a 5.
- **Método**: `POST`
- **URL**: `/movie/:id/rate`
- **Parâmetros de URL:**
- `id`: ID do filme.
- **Corpo da Requisição:**
```json
{
"rating": 5
}
```
- **Exemplo de Resposta:**
```json
{
"id": "ae44ae5b-7d56-483a-8283-289c784ee91d",
"title": "Interstellar",
"synopsis": "The adventures of a group of explorers who make use of a newly discovered wormhole to surpass the limitations on human space travel and conquer the vast distances involved in an interstellar voyage.",
"releaseYear": 2014,
"genre": "Adventure, Drama, Science Fiction",
"state": "RATED",
"rating": 5,
"createdAt": "2025-02-09T19:16:02.882Z"
}
```
### 📖 Histórico do Filme
- **Descrição:** Exibe o histórico de ações de um filme.
- **Método**: `GET`
- **URL**: `/movie/:id/history`
- **Parâmetros de URL:**
- `id`: ID do filme.
- **Exemplo de Resposta:**
```json
{
"movieId": "ae44ae5b-7d56-483a-8283-289c784ee91d",
"title": "Interstellar",
"history": [
{
"method": "GET",
"url": "/movie/ae44ae5b-7d56-483a-8283-289c784ee91d",
"status": 200,
"timestamp": "2025-02-09T19:17:32.334Z",
"user": "a945afc7-f5c3-40ee-a865-94f3623d8c16"
},
{
"method": "PUT",
"url": "/movie/ae44ae5b-7d56-483a-8283-289c784ee91d/state",
"status": 200,
"timestamp": "2025-02-09T19:18:05.061Z",
"user": "a945afc7-f5c3-40ee-a865-94f3623d8c16"
},
{
"method": "POST",
"url": "/movie/ae44ae5b-7d56-483a-8283-289c784ee91d/rate",
"status": 200,
"timestamp": "2025-02-09T19:18:37.476Z",
"user": "a945afc7-f5c3-40ee-a865-94f3623d8c16"
},
{
"method": "GET",
"url": "/movie/ae44ae5b-7d56-483a-8283-289c784ee91d/history",
"status": 200,
"timestamp": "2025-02-09T19:19:06.466Z",
"user": "a945afc7-f5c3-40ee-a865-94f3623d8c16"
}
]
}
```
### 📊 Logs das Requisições
- **Descrição:** Exibe os logs de todas as requisições feitas à API.
- **Método**: `GET`
- **URL**: `/log`
- **Exemplo de Resposta:**
```json
[
{
"id": "971962dd-2ce5-4c27-b3cc-3da71fe9d550",
"type": "REQUEST",
"method": "GET",
"url": "/movie/ae44ae5b-7d56-483a-8283-289c784ee91d/history",
"status": 200,
"timestamp": "2025-02-09T19:19:06.466Z",
"movieId": "ae44ae5b-7d56-483a-8283-289c784ee91d",
"userId": "a945afc7-f5c3-40ee-a865-94f3623d8c16"
},
{
"id": "1b540827-705a-4ee2-afba-536ef3d91558",
"type": "REQUEST",
"method": "POST",
"url": "/movie/ae44ae5b-7d56-483a-8283-289c784ee91d/rate",
"status": 200,
"timestamp": "2025-02-09T19:18:37.476Z",
"movieId": "ae44ae5b-7d56-483a-8283-289c784ee91d",
"userId": "a945afc7-f5c3-40ee-a865-94f3623d8c16"
},
{
"id": "261cab53-f903-4d38-8422-b64000017b78",
"type": "REQUEST",
"method": "PUT",
"url": "/movie/ae44ae5b-7d56-483a-8283-289c784ee91d/state",
"status": 200,
"timestamp": "2025-02-09T19:18:05.061Z",
"movieId": "ae44ae5b-7d56-483a-8283-289c784ee91d",
"userId": "a945afc7-f5c3-40ee-a865-94f3623d8c16"
},
{
"id": "b7f4ca7b-54aa-4e04-9d9d-85682ef065bf",
"type": "REQUEST",
"method": "GET",
"url": "/movie/ae44ae5b-7d56-483a-8283-289c784ee91d",
"status": 200,
"timestamp": "2025-02-09T19:17:32.334Z",
"movieId": "ae44ae5b-7d56-483a-8283-289c784ee91d",
"userId": "a945afc7-f5c3-40ee-a865-94f3623d8c16"
},
{
"id": "b61a3012-ad80-4f20-9955-815169876a53",
"type": "REQUEST",
"method": "GET",
"url": "/movie",
"status": 200,
"timestamp": "2025-02-09T19:16:55.628Z",
"movieId": null,
"userId": "a945afc7-f5c3-40ee-a865-94f3623d8c16"
},
{
"id": "e0e7f05d-27d0-465a-82ae-52dbf58142d0",
"type": "REQUEST",
"method": "POST",
"url": "/movie",
"status": 201,
"timestamp": "2025-02-09T19:16:02.278Z",
"movieId": "ae44ae5b-7d56-483a-8283-289c784ee91d",
"userId": "a945afc7-f5c3-40ee-a865-94f3623d8c16"
}
]
```
## 📝 Documentação da API com Swagger
A documentação da API foi criada utilizando **Swagger**. Você pode acessá-la em [http://localhost:3333/docs](http://localhost:3333/docs) após rodar a aplicação.
## 🧪 Testes
Este projeto utiliza o **Vitest** para garantir a confiabilidade e o funcionamento correto dos recursos implementados. Para executar os testes, utilize os seguintes comandos:
- **Executar testes:**
```bash
npm run test
```
- **Executar testes em modo de observação:**
```bash
npm run test:watch
```
- **Executar testes com cobertura:**
```bash
npm run test:coverage
```
## 🤝 Contribuições
Contribuições são bem-vindas! Sinta-se à vontade para abrir issues ou pull requests com melhorias ou correções. ✨
## ⭐ Apoie este Projeto
Se este projeto te ajudou ou te inspirou de alguma forma, não esqueça de deixar uma ⭐ no repositório! Isso faz toda a diferença! 🚀
## 📜 Licença
Este projeto está licenciado sob a [MIT License](LICENSE).
## 📞 Contato
[](https://www.linkedin.com/in/joschonarth/)
[](mailto:joschonarth@gmail.com)