{"id":36577839,"url":"https://github.com/demdxx/redify","last_synced_at":"2026-01-12T07:38:11.549Z","repository":{"id":64304659,"uuid":"425565710","full_name":"demdxx/redify","owner":"demdxx","description":"🧩 Redify any database as RedisDB","archived":false,"fork":false,"pushed_at":"2024-05-03T18:26:11.000Z","size":472,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-06-20T17:52:30.725Z","etag":null,"topics":["database","key-value-store","mssql","mysql","oracle","postgresql","redis","redis-server","sqlite"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/demdxx.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-07T17:09:58.000Z","updated_at":"2024-05-03T18:26:05.000Z","dependencies_parsed_at":"2024-01-04T13:45:28.286Z","dependency_job_id":"924a5b6e-65d2-445f-bbfa-533dc1dd7f17","html_url":"https://github.com/demdxx/redify","commit_stats":null,"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"purl":"pkg:github/demdxx/redify","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/demdxx%2Fredify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/demdxx%2Fredify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/demdxx%2Fredify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/demdxx%2Fredify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/demdxx","download_url":"https://codeload.github.com/demdxx/redify/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/demdxx%2Fredify/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28336612,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T06:09:07.588Z","status":"ssl_error","status_checked_at":"2026-01-12T06:05:18.301Z","response_time":98,"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":["database","key-value-store","mssql","mysql","oracle","postgresql","redis","redis-server","sqlite"],"created_at":"2026-01-12T07:38:11.041Z","updated_at":"2026-01-12T07:38:11.544Z","avatar_url":"https://github.com/demdxx.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Redify (Any database as redis)\n\n![License](https://img.shields.io/github/license/demdxx/redify)\n[![Docker Pulls](https://img.shields.io/docker/pulls/demdxx/redify.svg?maxAge=604800)](https://hub.docker.com/r/demdxx/redify)\n[![Go Report Card](https://goreportcard.com/badge/github.com/demdxx/redify)](https://goreportcard.com/report/github.com/demdxx/redify)\n[![Coverage Status](https://coveralls.io/repos/github/demdxx/redify/badge.svg?branch=main)](https://coveralls.io/github/demdxx/redify?branch=main)\n[![Testing Status](https://github.com/demdxx/redify/workflows/Tests/badge.svg)](https://github.com/demdxx/redify/actions?workflow=Tests)\n[![Publish Docker Status](https://github.com/demdxx/redify/workflows/Publish/badge.svg)](https://github.com/demdxx/redify/actions?workflow=Publish)\n\nRedify is a tool that makes it faster and easier to access and cache data from\nother databases. It does this by using Redis and/or HTTP protocol as a key-value\nproxy. It's useful for any web project that deals with content, as it can speed\nup data access and make it more reliable.\n\nModern websites consist of many small services that use different databases. To\nimprove data reading, a key-value storage for caches is often used. Redify simplifies\nthe process of creating content websites by using a widely-used protocol and\neliminating the need for complex application controllers and custom caches.\n\n## Build project\n\n```sh\nAPP_BUILD_TAGS=pgx,clickhouse,mysql,mssql,kafka,redispub,nats make build\n```\n\n```sh\nredify --conf docker/example.config.yml\n```\n\n## Run in docker\n\n```sh\ndocker run -v ./my.config.yml:/config.yml -it --rm demdxx/redify:latest --conf /config.yml\n```\n\n## Config example\n\n```yml\ncache:\n  # redis://host:port/{dbnum}?max_retries=0\u0026min_retry_backoff=10s\u0026max_retry_backoff=10s\u0026dial_timeout=3s\u0026read_timeout=3s\u0026write_timeout=3s\u0026pool_fifo=false\u0026pool_size=10\u0026min_idle_conns=60s\u0026max_conn_age=60s\u0026pool_timeout=300s\u0026idle=100s\u0026idle_check_frequency=3s\u0026ttl=200s\n  connect: \"memory\"\n  size: 1000 # Max capacity\n  ttl: 60s # Seconds\nsources:\n  - connect: \"clickhouse://dbuser:password@chdb:9000/project\"\n    binds:\n    - dbnum: 0\n      readonly: yes\n      reorganize_nested: yes # Reorganize nested fields to deep structure\n                             # Example: {\"a.b\": [1,2], \"a.c\": [\"X\",\"Y\"]} -\u003e {\"a\": [{\"b\": 1, \"c\": \"X\"}, {\"b\": 2, \"c\": \"Y\"}]}\n      table_name: \"events.event_local\"\n      key: \"event_{{id}}\"\n      datatype_mapping:\n        - name: a.b\n          type: int # json, string, int, float, bool\n  - connect: \"postgres://dbuser:password@pgdb:5432/project?sslmode=disable\"\n    # Predefined in the postgresql notification channel\n    notify_channel: redify_update\n    binds:\n    - dbnum: 0\n      key: \"post_{{slug}}\"\n      get_query: \"SELECT * FROM posts WHERE slug = {{slug}} AND deleted_at IS NULL LIMIT 1\"\n      list_query: \"SELECT slug FROM posts WHERE deleted_at IS NULL\"\n    - dbnum: 1\n      # Automaticaly prepare requests for table `users` with key field `username`\n      key: \"user_{{username}}\"\n      table_name: \"users\"\n      readonly: yes\n    - dbnum: 2\n      key: \"document_{{type}}_{{slug}}\"\n      get_query: |\n        SELECT * FROM documents WHERE type={{type}} AND slug={{slug}} AND deleted_at IS NULL LIMIT 1\n      list_query: |\n        SELECT type, slug FROM documents WHERE deleted_at IS NULL\n      upsert_query: |\n        INSERT INTO documents (slug, type, title, content)\n          VALUES ({{slug}},{{type}},{{title}},{{content}})\n          ON CONFLICT (slug, type) DO UPDATE SET title={{title}}, content={{content}}, deleted_at=NULL\n      del_query: |\n        UPDATE documents SET deleted_at=NOW() WHERE type={{type}} AND slug={{slug}}\n  - connect: \"mysql://dbuser:password@mysql:3306/project\"\n    binds:\n    - dbnum: 0\n      key: \"wp_post_{{slug}}\"\n      get_query: \"SELECT * FROM wp_posts WHERE slug = {{slug}} AND deleted_at IS NULL LIMIT 1\"\n      list_query: \"SELECT slug FROM wp_posts WHERE deleted_at IS NULL\"\n  - connect: nats://nats:4442/group?topics=news\n    binds:\n    - dbnum: 0\n      key: news_notify\n```\n\n## Redis using example\n\nFor using of Redis protocol.\n\n```sh\nexport SERVER_REDIS_LISTEN=:8081\nexport SERVER_REDIS_READ_TIMEOUT=120s\n```\n\n```sh\n\u003e redis-cli -p 8081 -h hostname\nhostname:8081\u003e keys *o*\n1) \"post_hello\"\n2) \"post_bye\"\n3) \"document_docx_main\"\n4) \"document_pdf_help\"\nhostname:8081\u003e get post_bye\n\"{\\\"content\\\":\\\"Bye everyone\\\",\\\"created_at\\\":\\\"2021-11-06T20:03:56.218629Z\\\",\\\"deleted_at\\\":null,\\\"id\\\":4,\\\"slug\\\":\\\"bye\\\",\\\"title\\\":\\\"Bye world\\\",\\\"updated_at\\\":\\\"2021-11-06T20:03:56.218629Z\\\"}\"\nhostname:8081\u003e hgetall post_hello\n 1) \"content\"\n 2) \"Hello everyone\"\n 3) \"created_at\"\n 4) \"2021-11-06T20:03:56.218629Z\"\n 5) \"deleted_at\"\n 6) \"null\"\n 7) \"id\"\n 8) \"3\"\n 9) \"slug\"\n10) \"hello\"\n11) \"title\"\n12) \"Hello world\"\n13) \"updated_at\"\n14) \"2021-11-06T20:03:56.218629Z\"\nhostname:8081\u003e hget post_hello title\n\"Hello world\"\n```\n\n## HTTP example\n\nFor using of HTTP protocol.\n\n```sh\nexport SERVER_HTTP_LISTEN=:8080\nexport SERVER_HTTP_READ_TIMEOUT=120s\n```\n\n\u003e GET /:dbnum/:key\n\n```sh\ncurl -XGET \"http://localhost:8080/0/post_hello\"\n{\"status\":\"OK\", \"result\":{\"content\":\"Hello everyone\",\"created_at\":\"2021-11-06T20:03:56.218629Z\",\"deleted_at\":null,\"id\":3,\"slug\":\"hello\",\"title\":\"Hello world\",\"updated_at\":\"2021-11-06T20:03:56.218629Z\"}}\n```\n\n\u003e PUT /:dbnum/:key\n\u003e POST /:dbnum/:key\n\n```sh\ncurl -d \"@data.json\" -XPOST \"http://localhost:8080/0/post_hello\"\n{\"status\":\"OK\"}\n```\n\n\u003e GET /:dbnum/keys/:pattern\n\n```sh\ncurl -XGET \"http://localhost:8080/0/keys/post_*\"\n{\"status\":\"OK\", \"result\":[\"post_post-1\",\"post_post-2\",\"post_hello\",\"post_bye\"]}\n```\n\n\u003e DELETE /:dbnum/:key\n\n```sh\ncurl -XDELETE \"http://localhost:8080/0/post_hello\"\n{\"status\":\"OK\"}\n```\n\n## Cache invalidation notifications\n\n### PostgreSQL\n\nPostgreSQL supports `pg_notify` precedure to notify about any kind of changes in data.\n\n```sql\nCREATE OR REPLACE FUNCTION notify_event() RETURNS TRIGGER AS $$\n\n    DECLARE\n        data json;\n        notification json;\n\n    BEGIN\n\n        -- Convert the old or new row to JSON, based on the kind of action.\n        -- Action = DELETE?             -\u003e OLD row\n        -- Action = INSERT or UPDATE?   -\u003e NEW row\n        IF (TG_OP = 'DELETE') THEN\n            data = row_to_json(OLD);\n        ELSE\n            data = row_to_json(NEW);\n        END IF;\n\n        -- Contruct the notification as a JSON string.\n        notification = json_build_object(\n                          'table',TG_TABLE_NAME,\n                          'action', TG_OP,\n                          'data', data);\n\n        -- Execute pg_notify(channel, notification)\n        PERFORM pg_notify('redify_update', notification::text);\n\n        -- Result is ignored since this is an AFTER trigger\n        RETURN NULL;\n    END;\n\n$$ LANGUAGE plpgsql;\n\nCREATE TRIGGER products_notify_event\nAFTER INSERT OR UPDATE OR DELETE ON products\n    FOR EACH ROW EXECUTE PROCEDURE notify_event();\n```\n\n## Event Streaming\n\nSometimes, it's helpful to use storage keys as a way to publish events to message\npublishing systems, such as queues. This approach can be used to publish events\nthat occur within a system, or to create pending actions.\n\n### Build\n\n```ss\nAPP_BUILD_TAGS=kafka,redispub,nats make build\n```\n\n### Config\n\n```yaml\nsources:\n  # (kafka|nats|redispub)://hostname:port/group_name?topics=name_in_stream\n  - connect: nats://nats:4442/group?topics=news\n    binds:\n    - dbnum: 0\n      key: news_notify\n```\n\n### Using\n\n```sh\nhostname:8081\u003e set news_notify '{\"action\":\"view\",\"id\":100,\"ts\":199991229912}'\nOK\n```\n\n## Support Redis commands\n\n* SELECT \\[dbnum\\]\n* KEYS \\[pattern\\]\n* GET key\n* MGET key1 key2 ... keyN\n* HGET key fieldname\n* HGETALL key\n* SET key value\n* MSET key1 value1 key2 value2 ... keyN valueN\n* PING\n* QUIT\n\n## TODO\n\n* [X] PGX PostgreSQL driver support\n* [X] MySQL driver support\n* [X] Sqlite driver support\n* [X] MSSQL driver support\n* [X] Oracle driver support\n* [X] Stream Publishing driver (Kafka,NATS,Redis Pub)\n* [X] Clickhouse driver support\n* [ ] Add personal cache to every bind separately\n* [ ] Cassandra driver support\n* [ ] MongoDB driver support\n* [ ] NextJS application example\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdemdxx%2Fredify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdemdxx%2Fredify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdemdxx%2Fredify/lists"}