{"id":15272400,"url":"https://github.com/pygzfei/gin-cache","last_synced_at":"2025-04-12T09:31:47.917Z","repository":{"id":40390814,"uuid":"452100829","full_name":"pygzfei/gin-cache","owner":"pygzfei","description":"gin easy to use memCache and redisCache","archived":false,"fork":false,"pushed_at":"2022-07-06T13:35:19.000Z","size":82,"stargazers_count":25,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-26T04:51:07.177Z","etag":null,"topics":["cache","gin","go"],"latest_commit_sha":null,"homepage":"","language":"Go","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/pygzfei.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}},"created_at":"2022-01-26T01:25:58.000Z","updated_at":"2025-01-16T10:23:39.000Z","dependencies_parsed_at":"2022-08-09T19:10:20.159Z","dependency_job_id":null,"html_url":"https://github.com/pygzfei/gin-cache","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pygzfei%2Fgin-cache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pygzfei%2Fgin-cache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pygzfei%2Fgin-cache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pygzfei%2Fgin-cache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pygzfei","download_url":"https://codeload.github.com/pygzfei/gin-cache/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248546107,"owners_count":21122254,"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":["cache","gin","go"],"created_at":"2024-09-30T09:06:03.544Z","updated_at":"2025-04-12T09:31:47.643Z","avatar_url":"https://github.com/pygzfei.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Release](https://img.shields.io/github/v/release/pygzfei/gin-cache.svg?style=flat-square)](https://github.com/pygzfei/gin-cache/releases)\n[![doc](https://img.shields.io/badge/go.dev-doc-007d9c?style=flat-square\u0026logo=read-the-docs)](https://pkg.go.dev/github.com/pygzfei/gin-cache)\n[![Build Status](https://github.com/pygzfei/gin-cache/actions/workflows/go.yml/badge.svg?branch=main)](https://github.com/pygzfei/gin-cache/actions?query=branch%3Amaster)\n[![Go Report Card](https://goreportcard.com/badge/github.com/pygzfei/gin-cache?branch=main)](https://goreportcard.com/report/github.com/pygzfei/gin-cache)\n[![codecov](https://codecov.io/gh/pygzfei/gin-cache/branch/main/graph/badge.svg)](https://codecov.io/gh/pygzfei/gin-cache)\n![](https://img.shields.io/badge/license-MIT-green)\n\n## Gin cache middleware\n\nEasy use of caching with Gin Handler Func\n\n## [中文](/README_CN.md)\n\n## Driver\n\n- [x] memory\n- [x] redis\n- [ ] more...\n\n## Install\n\n```\ngo get -u github.com/pygzfei/gin-cache\n```\n\n## Quick start\n\n```go\npackage main\n\nimport (\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/pygzfei/gin-cache/cmd/startup\"\n\t\"github.com/pygzfei/gin-cache/pkg/define\"\n\t\"time\"\n)\n\nfunc main() {\n\n\tcache, _ := startup.MemCache()\n\tr := gin.Default()\n\n\tr.GET(\"/ping\", cache.Handler(\n\t\tdefine.Caching{\n\t\t    Cacheable: []define.Cacheable{\n                    // params[\"id\"] is the request data from query or post data, for example: \n                    // http://domain/?id=1, the cache will be generated as: `anson:id:1`\n                    {GenKey: func(params map[string]interface{}) string {\n                        return fmt.Sprintf(\"anson:id:%s\", params[\"id\"])\n                    }},\n\t\t\t},\n\t\t},\n\t\tfunc(c *gin.Context) {\n\t\t\tc.JSON(200, gin.H{\n\t\t\t\t\"message\": \"pong\", // The returned data will be cached\n\t\t\t})\n\t\t},\n\t))\n\n\tr.Run()\n}\n\n```\n\n## Overwrite global cache time\n\n```go\ncache, _ := startup.MemCache()\n\nr := gin.Default()\n\nr.GET(\"/ping_for_timeout\", cache.Handler(\n    define.Caching{\n        Cacheable: []define.Cacheable{\n            {GenKey: func(params map[string]interface{}) string {\n                return fmt.Sprintf(\"anson:id:%s\u0026name=%s\", item.Id, item.Hash)\n            }, \n            // The effective time of the cache will be based on this time value instead of the global value\n            CacheTime: time.Second },\n        },\n    },\n    func(c *gin.Context) {\n       // ...\n    },\n))\n\n```\n\n## Trigger Cache evict\n\n```go\n// Post Body Json: {\"id\": 1}\n// The cache key value that will trigger invalidation is: `anson:userid:1`\nr.POST(\"/ping\", cache.Handler(\n    define.Caching{\n        Evict: []define.CacheEvict{\n            // params[\"id\"]  from Post Body Json `{\"id\": 1}`\n            func(params map[string]interface{}) string {\n                return fmt.Sprintf(\"anson:id:%s\", params[\"id\"])\n            },\n        },\n    },\n    func(c *gin.Context) {\n        // ...\n    },\n))\n\n// Wildcards '*' can also be used, e.g. 'anson:id:1*'\n// If this data exists in the cache list: [\"anson:id:1\", \"anson:id:12\", \"anson:id:3\"]\n// Then the cached data starting with `anson:id:1` will be deleted, and the cache list will remain: [\"anson:id:3\"]\nr.POST(\"/ping\", cache.Handler(\n    define.Caching{\n        Evict: []define.CacheEvict{\n            func(params map[string]interface{}) string {\n                return fmt.Sprintf(\"anson:id:%s*\", params[\"id\"])\n            },\n        },\n    },\n    func(c *gin.Context) {\n        // ...\n    },\n))\n```\n\n## Use Redis\n\n```go\ncache, _ := startup.RedisCache(time.Second*30, \u0026redis.Options{\n    Addr:     \"localhost:6379\",\n    Password: \"\",\n    DB:       0,\n})\n\t\n```\n\n## Hooks\n\ncache instance, returns \"application/json; Charset=utf-8\" by default\n\n```go\nctx.Writer.Header().Set(\"Content-Type\", \"application/json; Charset=utf-8\")\nctx.String(http.StatusOK, cacheValue)\nctx.Abort()\n````\n\nalso, can use the global Hook to intercept the return information\n\n```go\ncache, _ := startup.MemCache(timeout, func(c *gin.Context, cacheValue string) {\n    // cached value, which can be intercepted globally\n})\n\n```\n\nalso, use a separate Hook to intercept a message return\n\n```go\ncache, _ := startup.MemCache(timeout, func(c *gin.Context, cacheValue string) {\n    // will not be executed here\n})\n\nr.GET(\"/pings\", cache.Handler(\n    define.Caching{\n        Cacheable: []define.Cacheable{\n            GenKey: func(params map[string]interface{}) string {\n                return fmt.Sprintf(\"anson:userId:%s hash:%s\", params[\"id\"], params[\"hash\"])\n            },\n             onCacheHit: define.CacheHitHook{func(c *gin.Context, cacheValue string) {\n                // this will override the global interception of the cache\n                assert.True(t, len(cacheValue) \u003e 0)\n            }}},\n        },\n    },\n    func(c *gin.Context) {\n       //...\n    },\n))\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpygzfei%2Fgin-cache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpygzfei%2Fgin-cache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpygzfei%2Fgin-cache/lists"}