A GraphQL-based backend API for managing videos and user feedback, built with Node.js, TypeScript, and MongoDB.
- Video Management: Create and fetch videos with metadata
- Feedback System: Users can rate and comment on videos
- GraphQL API: Modern, type-safe API with Apollo Server
- MongoDB Integration: Scalable document-based data storage
- Docker Support: Containerized deployment with Docker Compose
- TypeScript: Full type safety and modern JavaScript features
src/
βββ app.ts # Express app configuration
βββ server.ts # Server entry point
βββ config/
β βββ database/mongo/ # MongoDB configuration
β β βββ index.ts # Database connection
β β βββ schema/ # Mongoose schemas
β β βββ feedback.ts
β β βββ video.ts
β βββ env/ # Environment configuration
β β βββ index.ts
β βββ graphql/ # GraphQL configuration
β β βββ index.ts # Apollo Server setup
β β βββ schema-loader.ts # Schema loading
β β βββ query.graphql # Query definitions
β β βββ mutation.graphql # Mutation definitions
β β βββ video.graphql # Video type definitions
β β βββ feedback.graphql # Feedback type definitions
β βββ repositories/ # Data access layer
β βββ feedback.interface.ts
β βββ feedback.repository.ts
β βββ videos.interface.ts
β βββ videos.repository.ts
βββ dto/ # Data Transfer Objects
β βββ create-feedback.dto.ts
β βββ fetch-videos.dto.ts
β βββ fetch-feedback-by-video-id.dto.ts
βββ models/ # Mongoose models
β βββ feedback.ts
β βββ video.ts
βββ resolvers/ # GraphQL resolvers
β βββ create-feedback.resolver.ts
β βββ fetch-videos.resolver.ts
βββ services/ # Business logic layer
βββ create-feedback.service.ts
βββ fetch-videos.service.ts
βββ fetch-feedback-by-video-id.service.ts
- Why: Clear separation of concerns for maintainability and testability
- Implementation: Three distinct layers - Presentation (resolvers), Business Logic (services), Data Access (repositories)
- Benefits: Easy to test individual layers, swap implementations, and scale
- Why: Define API contract first, then implement resolvers
- Implementation: Separate
.graphqlfiles for types, queries, and mutations - Benefits: Self-documenting API, better client-server contract, easier frontend development
- Why: Abstracts data access logic from business logic
- Implementation: Interface + implementation for each entity
- Benefits: Easy to swap data sources, testable, follows SOLID principles
- Why: Encapsulates business logic separately from data access
- Implementation: Services orchestrate repositories and transform data using DTOs
- Benefits: Reusable business logic, easier unit testing, single responsibility
- Why: Type-safe data contracts between layers
- Implementation: Separate DTOs for requests/responses, transforming DB models to API responses
- Benefits: Prevents data leakage, ensures API stability, clear data contracts
- Why: Latest LTS with improved V8 performance and ES modules support
- Benefits: Better memory management, faster startup, modern JavaScript features
- Decision: Chosen for performance and ecosystem maturity
- Why: Type safety and better developer experience
- Configuration: Strict mode with path mapping (
~/*aliases) - Benefits: Catch errors at compile time, better IntelliSense, self-documenting code
- Why: Single endpoint, type-safe queries, efficient data fetching
- Implementation: Apollo Server with schema-first approach
- Benefits: Clients request only needed data, reduces over-fetching, built-in documentation
- Why: Document-based storage fits GraphQL's flexible nature
- Implementation: Mongoose ODM for type safety and validation
- Benefits: Schema evolution, horizontal scaling, native JSON support
- Why: Minimal, unopinionated framework
- Benefits: Lightweight, flexible, large ecosystem
- Decision: Simple setup for GraphQL integration
- Why: Runtime type validation and schema parsing
- Benefits: Type-safe validation, better error messages, schema inference
- Decision: Chosen over Joi for TypeScript integration
- Why: Single tool for linting and formatting
- Benefits: Faster execution, simpler configuration, unified rules
- Decision: Modern alternative with better performance
- Why: Consistent development and deployment environment
- Benefits: Easy setup, reproducible builds, production parity
- Decision: Standard containerization approach
- Runtime: Node.js 22
- Language: TypeScript
- Framework: Express.js
- API: GraphQL with Apollo Server
- Database: MongoDB with Mongoose ODM
- Validation: Zod
- Linting: Biome
- Containerization: Docker & Docker Compose
- Node.js 22+
- MongoDB (or Docker)
- npm or yarn
git clone https://github.com/dev-mariana/globo-test
cd globo-testnpm installCreate a .env file in the root directory:
NODE_ENV=
MONGODB_URI=
PORT=docker-compose up -dnpm run devnpm run build
npm startThe server will start on http://localhost:8080
Visit http://localhost:8080/graphql to access the GraphQL Playground for interactive API exploration.
# Fetch all videos
query GetVideos {
videos {
id
title
url
feedbacks {
id
}
}
}
# Fetch feedback for a specific video
query GetFeedbackByVideo($videoId: ID!) {
feedbackByVideo(videoId: $videoId) {
id
rating
comment
user
video {
id
}
}
}# Create feedback for a video
mutation CreateFeedback($input: FeedbackInput!) {
createFeedback(input: $input) {
id
rating
comment
user
video {
id
}
}
}id: ID!- Unique identifiertitle: String!- Video titleurl: String!- Video URLfeedbacks: [Feedback!]- Associated feedback
id: ID!- Unique identifierrating: Int!- Rating (1-5)comment: String!- User commentuser: String!- Usernamevideo: Video!- Associated video
npm run dev- Start development server with hot reloadnpm run build- Build for productionnpm start- Start production servernpm run lint- Run Biome linter
This project uses Biome for linting and formatting:
npm run lint| Variable | Description | Default |
|---|---|---|
NODE_ENV |
Environment mode | development |
MONGODB_URI |
MongoDB connection string | Required |
PORT |
Server port | 3000 |
{
_id: ObjectId,
title: string,
url: string,
feedbacks: ObjectId[]
}{
_id: ObjectId,
rating: number,
comment: string,
user: string,
video: ObjectId
}MIT
Mariana Bastos
# 1. Start the database
docker-compose up -d
# 2. Install dependencies
npm install
# 3. Start the server
npm run dev
# 4. Open GraphQL Playground
open http://localhost:8080/graphqlThe API will be ready to accept GraphQL queries and mutations!