[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-10237":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":17,"compositeScore":19,"rankGlobal":9,"rankLanguage":9,"license":20,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":23,"hasPages":21,"topics":24,"createdAt":9,"pushedAt":9,"updatedAt":33,"readmeContent":34,"aiSummary":35,"trendingCount":15,"starSnapshotCount":15,"syncStatus":36,"lastSyncTime":37,"discoverSource":38},10237,"go-gin-example","eddycjy\u002Fgo-gin-example","eddycjy","An example of gin",null,"Go",7192,1626,135,37,0,1,4,10,70.63,"MIT License",false,"master",true,[25,26,27,28,29,30,31,32],"api","endless","gin","go","golang","gorm","jwt","swagger","2026-06-12 04:00:49","# Go Gin Example - Blog API[![rcard](https:\u002F\u002Fgoreportcard.com\u002Fbadge\u002Fgithub.com\u002FEDDYCJY\u002Fgo-gin-example)](https:\u002F\u002Fgoreportcard.com\u002Freport\u002Fgithub.com\u002FEDDYCJY\u002Fgo-gin-example) [![GoDoc](http:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fgo-documentation-blue.svg?style=flat-square)](https:\u002F\u002Fgodoc.org\u002Fgithub.com\u002FEDDYCJY\u002Fgo-gin-example) [![License](http:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-mit-blue.svg?style=flat-square)](https:\u002F\u002Fraw.githubusercontent.com\u002FEDDYCJY\u002Fgo-gin-example\u002Fmaster\u002FLICENSE)\n\nA production-ready RESTful blog API example built with Go and Gin framework, demonstrating real-world patterns and best practices.\n\n[简体中文](https:\u002F\u002Fgithub.com\u002FEDDYCJY\u002Fgo-gin-example\u002Fblob\u002Fmaster\u002FREADME_ZH.md)\n\n## Project Overview\n\nThis project is a comprehensive blog backend API system that provides complete article and tag management functionalities, along with features like JWT authentication, image upload, QR code generation, and Excel import\u002Fexport.\n\n## Tech Stack\n\n| Category | Technology |\n|----------|------------|\n| Language | Go |\n| Web Framework | [Gin](https:\u002F\u002Fgithub.com\u002Fgin-gonic\u002Fgin) |\n| ORM | [GORM](https:\u002F\u002Fgithub.com\u002Fjinzhu\u002Fgorm) |\n| Database | MySQL |\n| Cache | Redis (via [Redigo](https:\u002F\u002Fgithub.com\u002Fgomodule\u002Fredigo)) |\n| Authentication | JWT ([jwt-go](https:\u002F\u002Fgithub.com\u002Fdgrijalva\u002Fjwt-go)) |\n| Configuration | [go-ini](https:\u002F\u002Fgithub.com\u002Fgo-ini\u002Fini) |\n| API Documentation | [Swagger](https:\u002F\u002Fgithub.com\u002Fswaggo\u002Fgin-swagger) |\n| Excel Processing | [excelize](https:\u002F\u002Fgithub.com\u002F360EntSecGroup-Skylar\u002Fexcelize), [xlsx](https:\u002F\u002Fgithub.com\u002Ftealeg\u002Fxlsx) |\n| Image Processing | [freetype](https:\u002F\u002Fgithub.com\u002Fgolang\u002Ffreetype), [barcode](https:\u002F\u002Fgithub.com\u002Fboombuler\u002Fbarcode) |\n| Validation | [beego\u002Fvalidation](https:\u002F\u002Fgithub.com\u002Fastaxie\u002Fbeego\u002Fvalidation) |\n\n## Project Structure\n\n```\ngo-gin-example\u002F\n├── conf\u002F                       # Configuration files\n│   └── app.ini                 # Application configuration\n├── docs\u002F                       # Documentation\n│   ├── sql\u002F                    # Database scripts\n│   │   └── blog.sql            # Database schema\n│   └── swagger\u002F                # Swagger documentation\n├── middleware\u002F                 # Middleware\n│   └── jwt\u002F                    # JWT authentication middleware\n│       └── jwt.go\n├── models\u002F                     # Data models (ORM)\n│   ├── article.go              # Article model\n│   ├── auth.go                 # Auth model\n│   ├── models.go               # Database initialization\n│   └── tag.go                  # Tag model\n├── pkg\u002F                        # Shared packages\n│   ├── app\u002F                    # Application utilities\n│   │   ├── form.go             # Form binding\n│   │   ├── request.go          # Request handling\n│   │   └── response.go         # Response formatting\n│   ├── e\u002F                      # Error codes\n│   │   ├── cache.go            # Cache key constants\n│   │   ├── code.go             # Error code definitions\n│   │   └── msg.go              # Error messages\n│   ├── export\u002F                 # Excel export utilities\n│   │   └── excel.go\n│   ├── file\u002F                   # File utilities\n│   │   └── file.go\n│   ├── gredis\u002F                 # Redis client\n│   │   └── redis.go\n│   ├── logging\u002F                # Logging utilities\n│   │   ├── file.go\n│   │   └── log.go\n│   ├── qrcode\u002F                 # QR code generation\n│   │   └── qrcode.go\n│   ├── setting\u002F                # Configuration management\n│   │   └── setting.go\n│   ├── upload\u002F                 # Image upload utilities\n│   │   └── image.go\n│   └── util\u002F                   # Common utilities\n│       ├── jwt.go              # JWT utilities\n│       ├── md5.go              # MD5 hashing\n│       ├── pagination.go       # Pagination helper\n│       └── util.go\n├── routers\u002F                    # Route definitions\n│   ├── api\u002F                    # API handlers\n│   │   ├── v1\u002F                 # API v1 handlers\n│   │   │   ├── article.go      # Article endpoints\n│   │   │   └── tag.go          # Tag endpoints\n│   │   ├── auth.go             # Authentication endpoint\n│   │   └── upload.go           # Image upload endpoint\n│   └── router.go               # Route initialization\n├── runtime\u002F                    # Runtime resources\n│   ├── fonts\u002F                  # Font files\n│   └── qrcode\u002F                 # QR code resources\n├── service\u002F                    # Business logic layer\n│   ├── article_service\u002F        # Article services\n│   │   ├── article.go          # Article CRUD operations\n│   │   └── article_poster.go   # Poster generation\n│   ├── auth_service\u002F           # Auth services\n│   │   └── auth.go\n│   ├── cache_service\u002F          # Cache key generation\n│   │   ├── article.go\n│   │   └── tag.go\n│   └── tag_service\u002F            # Tag services\n│       └── tag.go\n├── Dockerfile                  # Docker build file\n├── Makefile                    # Build automation\n├── go.mod                      # Go module definition\n├── go.sum                      # Dependency checksums\n└── main.go                     # Application entry point\n```\n\n## Architecture\n\nThe project follows a layered architecture pattern:\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                      HTTP Requests                          │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                    Middleware Layer                         │\n│                   (JWT Authentication)                      │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                     Router Layer                            │\n│                (routers\u002Fapi\u002Fv1\u002F*.go)                        │\n│        - Request validation                                 │\n│        - Parameter binding                                  │\n│        - Response formatting                                │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                    Service Layer                            │\n│                   (service\u002F*\u002F*.go)                          │\n│        - Business logic                                     │\n│        - Cache management                                   │\n│        - Cross-model operations                             │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                     Model Layer                             │\n│                    (models\u002F*.go)                            │\n│        - Database operations                                │\n│        - CRUD methods                                       │\n│        - Data structures                                    │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                    Storage Layer                            │\n│              MySQL (Primary) + Redis (Cache)                │\n└─────────────────────────────────────────────────────────────┘\n```\n\n## Feature Tree\n\n```\nGo Gin Blog API\n├── Authentication\n│   └── JWT Login Validation\n│       ├── Token Generation (3-hour expiry)\n│       ├── Token Validation\n│       └── Token Refresh\n├── Article Management\n│   ├── Create Article\n│   ├── Read Article (with Redis caching)\n│   ├── Update Article\n│   ├── Delete Article (soft delete)\n│   ├── List Articles (paginated)\n│   ├── Count Articles\n│   └── Generate Article Poster\n│       ├── Embed QR Code\n│       ├── Apply Background Image\n│       ├── Render Text Overlay\n│       └── Save Merged Image\n├── Tag Management\n│   ├── CRUD Operations\n│   │   ├── Create Tag\n│   │   ├── Read Tags (paginated, cached)\n│   │   ├── Update Tag\n│   │   └── Delete Tag (soft delete)\n│   ├── Export Tags to Excel\n│   └── Import Tags from Excel\n├── File Upload\n│   └── Image Upload\n│       ├── Format validation (.jpg, .jpeg, .png)\n│       ├── Size validation (max 5MB)\n│       └── MD5-based naming\n├── API Documentation\n│   └── Swagger UI (\u002Fswagger\u002F*any)\n└── Static File Serving\n    ├── Exported Excel files (\u002Fexport)\n    ├── Uploaded images (\u002Fupload\u002Fimages)\n    └── Generated QR codes (\u002Fqrcode)\n```\n\n## API Endpoints\n\n### Public Endpoints\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| POST | `\u002Fauth` | User authentication, returns JWT token |\n| GET | `\u002Fswagger\u002F*any` | Swagger API documentation |\n| POST | `\u002Fupload` | Image upload |\n| POST | `\u002Ftags\u002Fexport` | Export tags to Excel |\n| POST | `\u002Ftags\u002Fimport` | Import tags from Excel |\n\n### Protected Endpoints (Require JWT Token)\n\n#### Tags\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| GET | `\u002Fapi\u002Fv1\u002Ftags` | Get tag list (paginated) |\n| POST | `\u002Fapi\u002Fv1\u002Ftags` | Create new tag |\n| PUT | `\u002Fapi\u002Fv1\u002Ftags\u002F:id` | Update tag by ID |\n| DELETE | `\u002Fapi\u002Fv1\u002Ftags\u002F:id` | Delete tag by ID |\n\n#### Articles\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| GET | `\u002Fapi\u002Fv1\u002Farticles` | Get article list (paginated) |\n| GET | `\u002Fapi\u002Fv1\u002Farticles\u002F:id` | Get article by ID |\n| POST | `\u002Fapi\u002Fv1\u002Farticles` | Create new article |\n| PUT | `\u002Fapi\u002Fv1\u002Farticles\u002F:id` | Update article by ID |\n| DELETE | `\u002Fapi\u002Fv1\u002Farticles\u002F:id` | Delete article by ID |\n| POST | `\u002Fapi\u002Fv1\u002Farticles\u002Fposter\u002Fgenerate` | Generate article poster with QR code |\n\n## Database Schema\n\n### Tables\n\n**blog_auth** - User authentication\n```sql\n- id: INT (PK, AUTO_INCREMENT)\n- username: VARCHAR(50)\n- password: VARCHAR(50)\n```\n\n**blog_tag** - Article tags\n```sql\n- id: INT (PK, AUTO_INCREMENT)\n- name: VARCHAR(100) - Tag name\n- created_on: INT - Creation timestamp\n- created_by: VARCHAR(100) - Creator\n- modified_on: INT - Modification timestamp\n- modified_by: VARCHAR(100) - Modifier\n- deleted_on: INT - Deletion timestamp (soft delete)\n- state: TINYINT - Status (0: disabled, 1: enabled)\n```\n\n**blog_article** - Articles\n```sql\n- id: INT (PK, AUTO_INCREMENT)\n- tag_id: INT (FK) - Associated tag ID\n- title: VARCHAR(100) - Article title\n- desc: VARCHAR(255) - Description\n- content: TEXT - Article content\n- cover_image_url: VARCHAR(255) - Cover image URL\n- created_on: INT - Creation timestamp\n- created_by: VARCHAR(100) - Creator\n- modified_on: INT - Modification timestamp\n- modified_by: VARCHAR(255) - Modifier\n- deleted_on: INT - Deletion timestamp (soft delete)\n- state: TINYINT - Status\n```\n\n## Configuration\n\nConfiguration is managed through `conf\u002Fapp.ini`:\n\n```ini\n[app]\nPageSize = 10                    # Pagination page size\nJwtSecret = 233                  # JWT signing secret\nPrefixUrl = http:\u002F\u002F127.0.0.1:8000\nRuntimeRootPath = runtime\u002F\nImageSavePath = upload\u002Fimages\u002F\nImageMaxSize = 5                 # Max image size in MB\nImageAllowExts = .jpg,.jpeg,.png\nExportSavePath = export\u002F\nQrCodeSavePath = qrcode\u002F\nFontSavePath = fonts\u002F\nLogSavePath = logs\u002F\n\n[server]\nRunMode = debug                  # debug or release\nHttpPort = 8000\nReadTimeout = 60                 # seconds\nWriteTimeout = 60                # seconds\n\n[database]\nType = mysql\nUser = root\nPassword = rootroot\nHost = 127.0.0.1:3306\nName = blog\nTablePrefix = blog_\n\n[redis]\nHost = 127.0.0.1:6379\nPassword =\nMaxIdle = 30\nMaxActive = 30\nIdleTimeout = 200\n```\n\n## Getting Started\n\n### Prerequisites\n\n- Go 1.13+\n- MySQL 5.6+\n- Redis\n\n### Database Setup\n\n1. Create a MySQL database named `blog`\n2. Execute the SQL script:\n```bash\nmysql -u root -p blog \u003C docs\u002Fsql\u002Fblog.sql\n```\n\n### Configuration\n\n1. Edit `conf\u002Fapp.ini` to match your environment\n2. Update database credentials\n3. Update Redis connection settings\n\n### Running the Application\n\n```bash\n# Build\nmake build\n\n# Run\n.\u002Fgo-gin-example\n\n# Or run directly\ngo run main.go\n```\n\nThe server will start at `http:\u002F\u002Flocalhost:8000`\n\n### Using Docker\n\n```bash\n# Build image\ndocker build -t go-gin-example .\n\n# Run container\ndocker run -p 8000:8000 go-gin-example\n```\n\n## API Usage Examples\n\n### 1. Get Authentication Token\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:8000\u002Fauth \\\n  -d \"username=test&password=test123\"\n```\n\nResponse:\n```json\n{\n  \"code\": 200,\n  \"msg\": \"ok\",\n  \"data\": {\n    \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\"\n  }\n}\n```\n\n### 2. Create a Tag\n\n```bash\ncurl -X POST \"http:\u002F\u002Flocalhost:8000\u002Fapi\u002Fv1\u002Ftags?token=YOUR_TOKEN\" \\\n  -d \"name=Go&created_by=admin&state=1\"\n```\n\n### 3. Get Tags List\n\n```bash\ncurl \"http:\u002F\u002Flocalhost:8000\u002Fapi\u002Fv1\u002Ftags?token=YOUR_TOKEN\"\n```\n\n### 4. Create an Article\n\n```bash\ncurl -X POST \"http:\u002F\u002Flocalhost:8000\u002Fapi\u002Fv1\u002Farticles?token=YOUR_TOKEN\" \\\n  -d \"tag_id=1&title=Hello Gin&desc=Introduction to Gin&content=Article content...&created_by=admin&cover_image_url=http:\u002F\u002Fexample.com\u002Fimage.jpg&state=1\"\n```\n\n### 5. Upload an Image\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:8000\u002Fupload \\\n  -F \"image=@\u002Fpath\u002Fto\u002Fimage.jpg\"\n```\n\n### 6. Export Tags to Excel\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:8000\u002Ftags\u002Fexport\n```\n\n## Key Design Patterns\n\n### 1. Soft Delete\nAll models use soft delete by setting `deleted_on` timestamp instead of actual deletion.\n\n### 2. Redis Caching\nArticles and tags are cached in Redis with 1-hour TTL to reduce database load.\n\n### 3. Service Layer Pattern\nBusiness logic is separated into service layer, keeping handlers thin and focused on request\u002Fresponse handling.\n\n### 4. Unified Response Format\nAll API responses follow consistent format:\n```json\n{\n  \"code\": 200,\n  \"msg\": \"ok\",\n  \"data\": {}\n}\n```\n\n### 5. Custom GORM Callbacks\nCustom callbacks for automatic timestamp management:\n- `CreatedOn` set on create\n- `ModifiedOn` updated on modifications\n- `DeletedOn` set on soft delete\n\n## Error Codes\n\n| Code | Description |\n|------|-------------|\n| 200 | Success |\n| 400 | Invalid parameters |\n| 500 | Internal server error |\n| 10001 | Tag already exists |\n| 10003 | Tag not found |\n| 10011 | Article not found |\n| 20001 | Token validation failed |\n| 20002 | Token expired |\n| 20003 | Token generation error |\n| 20004 | Authentication failed |\n| 30001 | Image save failed |\n| 30002 | Image check failed |\n| 30003 | Invalid image format |\n\n## Development Commands\n\n```bash\n# Build\nmake build\n\n# Run code analysis\nmake tool\n\n# Run linter\nmake lint\n\n# Clean build artifacts\nmake clean\n```\n\n## License\n\nMIT License - See [LICENSE](LICENSE) for details.\n\n## Credits\n\nProject by [EDDYCJY](https:\u002F\u002Fgithub.com\u002FEDDYCJY\u002Fgo-gin-example)\n","该项目是一个基于Go语言和Gin框架构建的生产级RESTful博客API示例，展示了实际开发中的模式和最佳实践。核心功能包括文章与标签管理、JWT认证、图片上传、二维码生成及Excel导入导出等。技术栈方面，使用了GORM作为ORM工具，MySQL作为数据库，并通过Redis实现缓存机制；此外还集成了Swagger用于API文档生成。适合需要快速搭建具备完整后端服务功能的博客应用或相似场景下使用。",2,"2026-06-11 03:27:21","top_topic"]