{"id":36466492,"url":"https://github.com/catmullet/one","last_synced_at":"2026-01-12T00:04:12.945Z","repository":{"id":56346753,"uuid":"307858020","full_name":"catmullet/one","owner":"catmullet","description":"🚥 Idempotency Handler, for making sure incoming requests are idempotent. Useful for payments, \"at least once delivery\" systems and more.","archived":false,"fork":false,"pushed_at":"2020-11-13T03:24:07.000Z","size":38,"stargazers_count":21,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-06-19T03:08:23.525Z","etag":null,"topics":["delivery","golang","idempotence","idempotency","idempotency-handler","idempotency-key","idempotent","idempotent-requests","payment","redis","storage"],"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/catmullet.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":"2020-10-27T23:57:16.000Z","updated_at":"2024-04-19T17:46:38.000Z","dependencies_parsed_at":"2022-08-15T17:00:58.570Z","dependency_job_id":null,"html_url":"https://github.com/catmullet/one","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/catmullet/one","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catmullet%2Fone","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catmullet%2Fone/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catmullet%2Fone/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catmullet%2Fone/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/catmullet","download_url":"https://codeload.github.com/catmullet/one/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catmullet%2Fone/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28328798,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T22:11:01.104Z","status":"ssl_error","status_checked_at":"2026-01-11T22:10:58.990Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["delivery","golang","idempotence","idempotency","idempotency-handler","idempotency-key","idempotent","idempotent-requests","payment","redis","storage"],"created_at":"2026-01-12T00:04:12.157Z","updated_at":"2026-01-12T00:04:12.935Z","avatar_url":"https://github.com/catmullet.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"![one logo](https://github.com/catmullet/one/blob/assets/one_logo.png)\n# _(īdəmˌpōtənt)_ Idempotency Handler\n## Description\nEasily check if you have recieved/processed an object before. Some examples may be:\n* Where PubSub services use _\"at least once delivery\"_\n* Cases of accepting requests to make payment\n* Deduping requests to your services\n\n## Getting Started\nimport the repo by running:\n```sh\ngo get github.com/catmullet/one\n```\nimport into your project\n```go\nimport github.com/catmullet/one\n```\n## Creating Keys\nThe `one.MakeKey()` function takes in an array of any type and creates a key. This key is specific to the parameters you have passed in.  If you pass in the exact same fields you will get the exact same key.  Its how we tell if we are getting the same request.  Choose Something that will give you a good indication that this is not the same object.  you can be as strict or relaxed as you want with it. \n\nTake for example this event from cloud storage\n```go\ntype Event struct {\n  Bucket string\n  Object string\n  Version int\n  UpdateTime time.Time\n}\n```\nIf you wanted to make sure that you never processed this storage object again you would use this:\n```go\nkey := one.MakeKey(event.Bucket, event.Object)\n```\nIf you wanted to make sure you processed on every version update you would use this:\n```go\nkey := one.MakeKey(event.Bucket, event.Object, event.Version)\n```\nIf you wanted to process based on any change to the storage object you could pass in the entire object like this:\n```go\nkey := one.MakeKey(event)\n```\n\n#### Redis\n```go\n// import \"gopkg.in/redis.v5\" for redis.Options\n\noptions := \u0026redis.Options{\n\t\tNetwork:            \"tcp\",\n\t\tAddr:               \"localhost:6379\",\n\t\tDialer:             nil,\n\t\tPassword:           \"\",\n\t\tDB:                 0,\n\t}\n  \nvar oneStore OneStore\noneStore = redisstore.NewRedisOneStore(options, time.Second * 30)\n```\n## Add Keys\n```go\nok, err := oneStore.Add(key)\nif !ok {\n  // Key already exists, so handle that here.\n}\n\n// Key doesn't exist and was added to the one store\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatmullet%2Fone","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcatmullet%2Fone","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatmullet%2Fone/lists"}