{"id":16606659,"url":"https://github.com/abdularis/gocommonweb","last_synced_at":"2026-06-22T02:31:43.674Z","repository":{"id":57571020,"uuid":"335944819","full_name":"abdularis/gocommonweb","owner":"abdularis","description":"common tools and functionality in web backend application","archived":false,"fork":false,"pushed_at":"2021-03-12T18:09:55.000Z","size":39,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-20T18:52:06.473Z","etag":null,"topics":["alibabacloud-oss","aws-s3","backend-api","go","jwt","redis"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/abdularis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-02-04T12:18:20.000Z","updated_at":"2021-03-12T18:09:58.000Z","dependencies_parsed_at":"2022-09-10T19:11:20.895Z","dependency_job_id":null,"html_url":"https://github.com/abdularis/gocommonweb","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/abdularis/gocommonweb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdularis%2Fgocommonweb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdularis%2Fgocommonweb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdularis%2Fgocommonweb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdularis%2Fgocommonweb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/abdularis","download_url":"https://codeload.github.com/abdularis/gocommonweb/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdularis%2Fgocommonweb/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34632536,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-22T02:00:06.391Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["alibabacloud-oss","aws-s3","backend-api","go","jwt","redis"],"created_at":"2024-10-12T01:09:32.730Z","updated_at":"2026-06-22T02:31:43.656Z","avatar_url":"https://github.com/abdularis.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Go Common Web 📦🌏\n\nContains utilities and tools commonly used in web application.\n\n\n## Install\n\n```\ngo get github.com/abdularis/gocommonweb@v0.1.0\n```\n\n## Components\n- [Cache](#cache)\n- [Event](#event)\n- [JWT](#jwt)\n- [Queue](#queue)\n- [Scheduler](#scheduler)\n- [Storage](#storage)\n- [WebSocket](#websocket)\n- [Other Utils](#other-utilities)\n\n### Cache\n\nProvides general purpose simple key value pair caching mechanism implemented using redis.\n\nUsage:\n```go\n// new cache implemented using redis\ncache := framework.NewCacheRedis(redisClient, \"starter-app\")\n\n// put in cache forever\ncache.Put(\"key0\", \"you data payload here\")\n\n// this will disappear in 1 minute\ncache.PutWithTTL(\"key1\", \"your data payload here\", time.Minute)\n\n// \nvalue, err := cache.Get(\"key1\")\n```\n\n### Event\n\nEvent is a pub/sub mechanism, provided implementation using redis pub/sub.\n\u003e note that redis pub/sub is broadcast\n\nUsage:\n```go\ntype mySubscription struct {}\n\nfunc (s mySubscription) Handle(eventName string, payload string) {\n\t// will print 'event occurred su_server_0\n\tfmt.Printf(\"event occurred %s\\n\", eventName)\n}\n\nfunc main() {\n    event := framework.NewEventRedis(redisCli)\n    \n    // subscribe to an event called 'sub_server_0' with mySubscription as handler that\n    // will be called when event published by other\n    event.Subscribe(\"sub_server_0\", \u0026mySubscription{})\n    \n    go func() {\n    \t// publish event that will be handle by subscriber\n    \tevent.Publish(\"sub_server_0\", \"\")\n    }()\n    \n    time.Sleep(time.Minute)\n    \n    event.Unsubscribe(\"sub_server_0\")\n}\n```\n\n### JWT\n\nProvide functionality to generate JWS/JWE token and verify them with given private key\n\nUsage:\n```go\nconfig := framework.JWTConfig{\n\tSignatureAlgo:      jwa.RS256,\n\tEnableJWE:          true,\n\tKeyEncryptAlgo:     jwa.RSA1_5,\n\tContentEncryptAlgo: jwa.A128CBC_HS256,\n\tJWECompressAlgo:    jwa.NoCompress,\n}\n\npemKey := framework.GenerateRSAPrivateKey(2048)\njwtUtil := framework.NewJWTUtilWithPEM(string(pemKey), config)\n\n\nvar claims map[string]interface{}\nclaims[\"email\"] = \"aris@gmail.com\"\n\ntoken, err := jwtUtil.GenerateJWT(claims)\nif err != nil {\n    panic(err)\n}\n\njwtTkn, err := jwtUtil.VerifyJWT(token)\nif err != nil {\n    panic(err)\n}\n```\n\n### Queue\n\nQueue provide common job queuing functionality for asynchronous execution.\nImplemented using database `queue_db.go` or using redis `queue_redis.go`\n\nUsage:\n```go\ntype sendEmailHandler struct {}\n\nfunc (s sendEmailHandler) Handle(jobName string, payload string) error {\n    // Send email logic here\n}\n\nfunc main() {\n    queue := framework.NewQueueDB(gormDB, 5)\n\n    // first add job handler that will be called if there is a job needs to be run\n    queue.AddJobHandler(\"send_email\", \u0026sendEmailHandler{})\n\n    // queue the job\n    queue.AddJob(\"send_email\", \"aris@gmail.com\")\n\n    // execute job after 30 secs\n    queue.AddDelayedJob(\"send_email\", \"aris@gmail.com\", 30)\n\n    // stop queue\n    queue.Stop()\n}\n```\n\n### Scheduler\n\nImplement periodic job scheduler, you provide cron spec as it's scheduling pattern. this implementation is safe to run on multiple instances, but at the same time only one job for a particular schedule will be run.\n\n\u003e note that this is implemented using redis, all scheduler instance will schedule and when there is an overdue job it will acquire a lock for that job and only one instance would win\n\nUsage:\n```go\n// create new scheduler, provide multiple redisClient master instance for global lock safety see NewScheduler() docs\ns := framework.NewScheduler(redisClient)\n\n// provide standard cron spec for schedule specification\ns.ScheduleJob(\"send_email_promo\", \"@every 5h\", func(execTime time.Time, jobName string, cronSpec string) {\n\t// this will be called every 5 hour\n\tfmt.Println(\"send email promotion logic here\")\n})\n\n// start scheduling worker\ns.Start()\ndefer s.Stop()\n\ntime.Sleep(time.Hour)\n```\n\n### Storage\n\nProvide storage abstraction for working with files/persistence object.\n\nStorage implementation:\n- `AWS S3`\n- `Alibaba OSS`\n- `Local File Storage`\n\nUsage:\n\n```go\n// first param is where the private file will be stored\n// second param is where the public hosted file will be stored (note that this directory needs to be served by your web server to give access)\n// third param is the base url for this hosted file, it is use to generate URL from object key (path) and append this base url to build full url\nstorage := framework.NewStorageLocalFile(\"./storage/private\", \"./storage/public\", \"http://localhost/files\")\n\nstream, err := storage.Read(\"users/images/profile.jpg\")\n```\n\n### WebSocket\n\nWebSocket provide full-duplex communication between user and server. You can run multiple websocket server, if you send\na message to a particular user connection that is not connected in the same server it will find the server where the\nclient is connected to and push via that server. This mechanism handled by redis to store all connection sessions\nand [Event](#event) for server-to-server communication.\n\n\n### Other Utilities\n\n**Password Hash**\n\nbcrypt password hash function\n\nUsage:\n```go\nhashed, err := framework.HashPassword(\"your_password\")\nif err != nil {\n    panic(err)\n}\n\nvalid := framework.CheckPasswordHash(\"your_password\", hashed)\nif valid {\n    fmt.Println(\"your password correct\")\n}\n```\n\n\n\u003e Note: *queue_redis.go* implemented using *gocraft* which used *redigo* redis client, whereas other tools such as *event* and *cache* using *goredis* as its redis client which has more convenient API. Therefore leads to using two different library with the same purpose indirectly.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabdularis%2Fgocommonweb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabdularis%2Fgocommonweb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabdularis%2Fgocommonweb/lists"}