[김영준 : Go] Good-Night-2nd-Hackathon-Backend 제출#10
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR adds a complete Go-based movie review API backend for a hackathon submission. The implementation uses a clean architecture pattern with separate layers for delivery, usecase, repository, and domain models, implementing CRUD operations for both movies and reviews with MySQL as the database.
- Complete movie review API implementation with movies and reviews endpoints
- Clean architecture pattern with clear separation of concerns
- Docker containerization with MySQL database setup
- Swagger documentation for API endpoints
Reviewed Changes
Copilot reviewed 31 out of 33 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| mysql/init.sql | Database initialization script for movie_review database |
| mysql/Dockerfile | MySQL container configuration with ARM64 support |
| movieReview/main.go | Main application entry point with Gin router setup |
| movieReview/config/ | Database connection and environment configuration |
| movieReview/movie/ | Complete movie domain implementation with CRUD operations |
| movieReview/review/ | Complete review domain implementation with filtering |
| docker-compose.yml | Multi-container setup for database and application |
| movieReview/docs/ | Auto-generated Swagger documentation |
| .env | Environment variables for database configuration |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
| @@ -0,0 +1,3 @@ | |||
| FROM arm64v8/mysql:8.0.30 | |||
There was a problem hiding this comment.
Using a specific ARM64 MySQL image limits portability. Consider using the official multi-platform mysql:8.0.30 image instead, which supports both ARM64 and AMD64 architectures automatically.
| FROM arm64v8/mysql:8.0.30 | |
| FROM mysql:8.0.30 |
| "GROUP BY movies.id "+ | ||
| "ORDER BY ScoreAvg DESC "+ | ||
| "LIMIT ? OFFSET ?", | ||
| params.Size-1, (params.Page-1)*params.Size, |
There was a problem hiding this comment.
The LIMIT calculation is incorrect. Using 'params.Size-1' will return one fewer record than requested. It should be 'params.Size' to return the correct number of records per page.
| params.Size-1, (params.Page-1)*params.Size, | |
| params.Size, (params.Page-1)*params.Size, |
| PORT := env.GetEnv("DB_PORT", "3306") | ||
| DBNAME := env.GetEnv("DB_NAME", "movie_review") | ||
| URL := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", USER, PASS, HOST, PORT, DBNAME) | ||
| fmt.Println(URL) |
There was a problem hiding this comment.
Printing the database URL to console exposes sensitive credentials (password) in logs. Remove this line or mask the password in the output.
| fmt.Println(URL) |
| @@ -0,0 +1,13 @@ | |||
| FROM golang:1.19 | |||
There was a problem hiding this comment.
The Dockerfile uses Go 1.19 but go.mod specifies Go 1.20. Update the Dockerfile to use 'golang:1.20' to match the module requirements.
| FROM golang:1.19 | |
| FROM golang:1.20 |
| type Review struct { | ||
| gorm.Model | ||
| MovieID uint `gorm:"foreignKey:MovieID"` | ||
| Movie domain.Movie |
There was a problem hiding this comment.
The foreignKey tag is incorrectly applied to the field instead of the association. It should be applied to the Movie field: Movie domain.Movie gorm:"foreignKey:MovieID"`
| Movie domain.Movie | |
| MovieID uint | |
| Movie domain.Movie `gorm:"foreignKey:MovieID"` |
| env_file: | ||
| - .env | ||
| environment: | ||
| - CHARACTER_SET_SERVER=utf8% |
There was a problem hiding this comment.
Invalid character set value 'utf8%'. It should be 'utf8mb4' to match the command line arguments.
| - CHARACTER_SET_SERVER=utf8% | |
| - CHARACTER_SET_SERVER=utf8mb4 |
|
|
||
| res, err := d.useCase.FindAllByMovieId(params) | ||
| if err != nil { | ||
| c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": err.Error()}) |
There was a problem hiding this comment.
Using StatusNotFound for database query errors is incorrect. Database errors should return StatusInternalServerError (500), while StatusNotFound (404) should only be used when no records are found intentionally.
| c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": err.Error()}) | |
| // TODO: Distinguish "not found" errors from other errors if possible. | |
| c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) |
개발환경
📝 실행 방법
실행
Swagger
주의사항