{"id":13412227,"url":"https://github.com/philippgille/gokv","last_synced_at":"2025-05-15T15:07:20.755Z","repository":{"id":33258665,"uuid":"152130551","full_name":"philippgille/gokv","owner":"philippgille","description":"Simple key-value store abstraction and implementations for Go (Redis, Consul, etcd, bbolt, BadgerDB, LevelDB, Memcached, DynamoDB, S3, PostgreSQL, MongoDB, CockroachDB and many more)","archived":false,"fork":false,"pushed_at":"2024-06-07T16:10:37.000Z","size":775,"stargazers_count":746,"open_issues_count":41,"forks_count":69,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-11-11T09:13:04.388Z","etag":null,"topics":["abstraction","badgerdb","bolt","boltdb","cloud-storage","consul","database","dynamodb","etcd","go","golang","key-value","key-value-store","library","memcached","mongodb","package","postgresql","redis","simple"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/philippgille.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2018-10-08T18:55:22.000Z","updated_at":"2024-11-04T17:23:58.000Z","dependencies_parsed_at":"2022-06-26T01:52:35.050Z","dependency_job_id":"0ac8e5fa-d51e-4da8-a1b0-40a4feb26f9d","html_url":"https://github.com/philippgille/gokv","commit_stats":null,"previous_names":[],"tags_count":66,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philippgille%2Fgokv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philippgille%2Fgokv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philippgille%2Fgokv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philippgille%2Fgokv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/philippgille","download_url":"https://codeload.github.com/philippgille/gokv/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254364270,"owners_count":22058878,"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":["abstraction","badgerdb","bolt","boltdb","cloud-storage","consul","database","dynamodb","etcd","go","golang","key-value","key-value-store","library","memcached","mongodb","package","postgresql","redis","simple"],"created_at":"2024-07-30T20:01:22.358Z","updated_at":"2025-05-15T15:07:18.484Z","avatar_url":"https://github.com/philippgille.png","language":"Go","funding_links":[],"categories":["Go","数据库驱动程序","Key/Value Databases","Database Drivers","Uncategorized","Generators","Data Integration Frameworks","NoSQL Databases","数据库驱动`连接和操作数据库工具`","数据库驱动"],"sub_categories":["多个后端接口","Interfaces to Multiple Backends","Uncategorized","Advanced Console UIs","SQL 查询语句构建库"],"readme":"gokv\n====\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/philippgille/gokv.svg)](https://pkg.go.dev/github.com/philippgille/gokv)\n[![Build status](https://github.com/philippgille/gokv/actions/workflows/test.yml/badge.svg)](https://github.com/philippgille/gokv/actions/workflows/test.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/philippgille/gokv)](https://goreportcard.com/report/github.com/philippgille/gokv)\n[![codecov](https://codecov.io/gh/philippgille/gokv/branch/master/graph/badge.svg)](https://codecov.io/gh/philippgille/gokv)\n[![GitHub Releases](https://img.shields.io/github/release/philippgille/gokv.svg)](https://github.com/philippgille/gokv/releases)\n[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)\n\nSimple key-value store abstraction and implementations for Go\n\nContents\n--------\n\n1. [Features](#features)\n   1. [Simple interface](#simple-interface)\n   2. [Implementations](#implementations)\n   3. [Value types](#value-types)\n   4. [Marshal formats](#marshal-formats)\n   5. [Roadmap](#roadmap)\n2. [Usage](#usage)\n   1. [Examples](#examples)\n3. [Project status](#project-status)\n4. [Motivation](#motivation)\n5. [Design decisions](#design-decisions)\n6. [Related projects](#related-projects)\n7. [License](#license)\n\nFeatures\n--------\n\n### Simple interface\n\n\u003e Note: The interface is not final yet! See [Project status](#project-status) for details.\n\n```go\ntype Store interface {\n    Set(k string, v any) error\n    Get(k string, v any) (found bool, err error)\n    Delete(k string) error\n    Close() error\n}\n```\n\nThere are detailed descriptions of the methods in the [docs](https://pkg.go.dev/badge/github.com/philippgille/gokv#Store) and in the [code](https://github.com/philippgille/gokv/blob/master/store.go). You should read them if you plan to write your own `gokv.Store` implementation or if you create a Go package with a method that takes a `gokv.Store` as parameter, so you know exactly what happens in the background.\n\n### Implementations\n\nSome of the following databases aren't specifically engineered for storing key-value pairs, but if someone's running them already for other purposes and doesn't want to set up one of the proper key-value stores due to administrative overhead etc., they can of course be used as well. In those cases let's focus on a few of the most popular though. This mostly goes for the SQL, NoSQL and NewSQL categories.\n\nFeel free to suggest more stores by creating an [issue](https://github.com/philippgille/gokv/issues) or even add an actual implementation - [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com).\n\nFor differences between the implementations, see [Choosing an implementation](docs/choosing-implementation.md).  \nFor the Godoc of specific implementations, see \u003chttps://pkg.go.dev/github.com/philippgille/gokv#section-directories\u003e.\n\n- Local in-memory\n  - [X] Go `sync.Map`\n  - [X] Go `map` (with `sync.RWMutex`)\n  - [X] [FreeCache](https://github.com/coocood/freecache)\n  - [X] [BigCache](https://github.com/allegro/bigcache)\n- Embedded\n  - [X] [bbolt](https://github.com/etcd-io/bbolt) (formerly known as [Bolt / Bolt DB](https://github.com/boltdb/bolt))\n  - [X] [BadgerDB](https://github.com/dgraph-io/badger)\n  - [X] [LevelDB / goleveldb](https://github.com/syndtr/goleveldb)\n  - [X] Local files (one file per key-value pair, with the key being the filename and the value being the file content)\n- Distributed store\n  - [X] [Redis](https://github.com/antirez/redis)\n  - [X] [Consul](https://github.com/hashicorp/consul)\n  - [X] [etcd](https://github.com/etcd-io/etcd)\n  - [X] [Apache ZooKeeper](https://github.com/apache/zookeeper)\n  - [ ] [TiKV](https://github.com/tikv/tikv)\n- Distributed cache (no presistence *by default*)\n  - [X] [Memcached](https://github.com/memcached/memcached)\n  - [X] [Hazelcast](https://github.com/hazelcast/hazelcast)\n- Cloud\n  - [X] [Amazon DynamoDB](https://aws.amazon.com/dynamodb/)\n  - [X] [Amazon S3](https://aws.amazon.com/s3/) / [Google Cloud Storage](https://cloud.google.com/storage/) / [Alibaba Cloud Object Storage Service (OSS)](https://www.alibabacloud.com/en/product/oss) / [DigitalOcean Spaces](https://www.digitalocean.com/products/spaces/) / [Scaleway Object Storage](https://www.scaleway.com/object-storage/) / [OpenStack Swift](https://github.com/openstack/swift) / [Ceph](https://github.com/ceph/ceph) / [Minio](https://github.com/minio/minio) / ...\n  - [ ] [Azure Cosmos DB](https://azure.microsoft.com/en-us/services/cosmos-db/)\n  - [X] [Azure Table Storage](https://azure.microsoft.com/en-us/services/storage/tables/)\n  - [X] [Google Cloud Datastore](https://cloud.google.com/datastore/)\n  - [ ] [Google Cloud Firestore](https://cloud.google.com/firestore/)\n  - [X] [Alibaba Cloud Table Store](https://www.alibabacloud.com/de/product/table-store)\n- SQL\n  - [X] [MySQL](https://github.com/mysql/mysql-server)\n  - [X] [PostgreSQL](https://github.com/postgres/postgres)\n- NoSQL\n  - [X] [MongoDB](https://github.com/mongodb/mongo)\n  - [ ] [Apache Cassandra](https://github.com/apache/cassandra)\n- \"NewSQL\"\n  - [X] [CockroachDB](https://github.com/cockroachdb/cockroach)\n  - [ ] [TiDB](https://github.com/pingcap/tidb)\n- Multi-model\n  - [X] [Apache Ignite](https://github.com/apache/ignite)\n  - [ ] [ArangoDB](https://github.com/arangodb/arangodb)\n  - [ ] [OrientDB](https://github.com/orientechnologies/orientdb)\n- Misc\n  - [X] Go `noop` does nothing except validate the inputs, if applicable.\n\nAgain:  \nFor differences between the implementations, see [Choosing an implementation](docs/choosing-implementation.md).  \nFor the Godoc of specific implementations, see \u003chttps://pkg.go.dev/github.com/philippgille/gokv#section-directories\u003e.\n\n### Value types\n\nMost Go packages for key-value stores just accept a `[]byte` as value, which requires developers for example to marshal (and later unmarshal) their structs. `gokv` is meant to be simple and make developers' lifes easier, so it accepts any type (with using `any`/`interface{}` as parameter), including structs, and automatically (un-)marshals the value.\n\nThe kind of (un-)marshalling is left to the implementation. All implementations in this repository currently support JSON and [gob](https://blog.golang.org/gobs-of-data) by using the `encoding` subpackage in this repository, which wraps the core functionality of the standard library's `encoding/json` and `encoding/gob` packages. See [Marshal formats](#marshal-formats) for details.\n\nFor unexported struct fields to be (un-)marshalled to/from JSON/gob, the respective custom (un-)marshalling methods need to be implemented as methods of the struct (e.g. `MarshalJSON() ([]byte, error)` for custom marshalling into JSON). See [Marshaler](https://pkg.go.dev/encoding/json#Marshaler) and [Unmarshaler](https://pkg.go.dev/encoding/json#Unmarshaler) for JSON, and [GobEncoder](https://pkg.go.dev/encoding/gob#GobEncoder) and [GobDecoder](https://pkg.go.dev/encoding/gob#GobDecoder) for gob.\n\nTo improve performance you can also implement the custom (un-)marshalling methods so that no reflection is used by the `encoding/json` / `encoding/gob` packages. This is not a disadvantage of using a generic key-value store package, it's the same as if you would use a concrete key-value store package which only accepts `[]byte`, requiring you to (un-)marshal your structs.\n\n### Marshal formats\n\nThis repository contains the subpackage `encoding`, which is an abstraction and wrapper for the core functionality of packages like `encoding/json` and `encoding/gob`. The currently supported marshal formats are:\n\n- [X] JSON\n- [X] [gob](https://blog.golang.org/gobs-of-data)\n- [X] [protobuf](https://pkg.go.dev/google.golang.org/protobuf)\n\nMore formats will be supported in the future (e.g. XML).\n\nThe stores use this `encoding` package to marshal and unmarshal the values when storing / retrieving them. The default format is JSON, but all `gokv.Store` implementations in this repository also support [gob](https://blog.golang.org/gobs-of-data) as alternative, configurable via their `Options`.\n\nThe marshal format is up to the implementations though, so package creators using the `gokv.Store` interface as parameter of a function should not make any assumptions about this. If they require any specific format they should inform the package user about this in the GoDoc of the function taking the store interface as parameter.\n\nDifferences between the formats:\n\n- Depending on the struct, one of the formats might be faster\n- Depending on the struct, one of the formats might lead to a lower storage size\n- Depending on the use case, the custom (un-)marshal methods of one of the formats might be easier to implement\n  - JSON: [`MarshalJSON() ([]byte, error)`](https://pkg.go.dev/encoding/json#Marshaler) and [`UnmarshalJSON([]byte) error`](https://pkg.go.dev/encoding/json#Unmarshaler)\n  - gob: [`GobEncode() ([]byte, error)`](https://pkg.go.dev/encoding/gob#GobEncoder) and [`GobDecode([]byte) error`](https://pkg.go.dev/encoding/gob#GobDecoder)\n  - protobuf: [`Marshal(proto.Message) ([]byte, error)`](https://pkg.go.dev/google.golang.org/protobuf/proto#Marshal) and [`Unmarshal([]byte, proto.Message) error`](https://pkg.go.dev/google.golang.org/protobuf/proto#Unmarshal)\n\n### Roadmap\n\n- Benchmarks!\n- CLI: A simple command line interface tool that allows you create, read, update and delete key-value pairs in all of the `gokv` storages\n- A `combiner` package that allows you to create a `gokv.Store` which forwards its call to multiple implementations at the same time. So for example you can use `memcached` and `s3` simultaneously to have 1) super fast access but also 2) durable redundant persistent storage.\n- A way to directly configure the clients via the options of the underlying used Go package (e.g. not the `redis.Options` struct in `github.com/philippgille/gokv`, but instead the `redis.Options` struct in `github.com/go-redis/redis`)\n  - Will be optional and discouraged, because this will lead to compile errors in code that uses `gokv` when switching the underlying used Go package, but definitely useful for some people\n- More stores (see stores in [Implementations](#implementations) list with unchecked boxes)\n- Maybe rename the project from `gokv` to `SimpleKV`?\n- Maybe move all implementation packages into a subdirectory, e.g. `github.com/philippgille/gokv/store/redis`?\n\nUsage\n-----\n\nFirst, download the [module](https://github.com/golang/go/wiki/Modules) you want to work with:\n\n- For example when you want to work with the `gokv.Store` interface:\n  - `go get github.com/philippgille/gokv@latest`\n- For example when you want to work with the Redis implementation:\n  - `go get github.com/philippgille/gokv/redis@latest`\n\nThen you can import and use it.\n\nEvery implementation has its own `Options` struct, but all implementations have a `NewStore()` / `NewClient()` function that returns an object of a sctruct that implements the `gokv.Store` interface. Let's take the implementation for Redis as example, which is the most popular distributed key-value store.\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n\n    \"github.com/philippgille/gokv\"\n    \"github.com/philippgille/gokv/redis\"\n)\n\ntype foo struct {\n    Bar string\n}\n\nfunc main() {\n    options := redis.DefaultOptions // Address: \"localhost:6379\", Password: \"\", DB: 0\n\n    // Create client\n    client, err := redis.NewClient(options)\n    if err != nil {\n        panic(err)\n    }\n    defer client.Close()\n\n    // Store, retrieve, print and delete a value\n    interactWithStore(client)\n}\n\n// interactWithStore stores, retrieves, prints and deletes a value.\n// It's completely independent of the store implementation.\nfunc interactWithStore(store gokv.Store) {\n    // Store value\n    val := foo{\n        Bar: \"baz\",\n    }\n    err := store.Set(\"foo123\", val)\n    if err != nil {\n        panic(err)\n    }\n\n    // Retrieve value\n    retrievedVal := new(foo)\n    found, err := store.Get(\"foo123\", retrievedVal)\n    if err != nil {\n        panic(err)\n    }\n    if !found {\n        panic(\"Value not found\")\n    }\n\n    fmt.Printf(\"foo: %+v\", *retrievedVal) // Prints `foo: {Bar:baz}`\n\n    // Delete value\n    err = store.Delete(\"foo123\")\n    if err != nil {\n        panic(err)\n    }\n}\n```\n\nAs described in the comments, that code does the following:\n\n1. Create a client for Redis\n   - Some implementations' stores/clients don't require to be closed, but when working with the interface (for example as function parameter) you *must* call `Close()` because you don't know which implementation is passed. Even if you work with a specific implementation you *should* always call `Close()`, so you can easily change the implementation without the risk of forgetting to add the call.\n2. Call `interactWithStore()`, which requires a `gokv.Store` as parameter. This method then:\n    1. Stores an object of type `foo` in the Redis server running on `localhost:6379` with the key `foo123`\n    2. Retrieves the value for the key `foo123`\n        - The check if the value was found isn't needed in this example but is included for demonstration purposes\n    3. Prints the value. It prints `foo: {Bar:baz}`, which is exactly what was stored before.\n    4. Deletes the value\n\nNow let's say you don't want to use Redis but Consul instead. You just have to make three simple changes:\n\n1. Replace the import of `\"github.com/philippgille/gokv/redis\"` by `\"github.com/philippgille/gokv/consul\"`\n2. Replace `redis.DefaultOptions` by `consul.DefaultOptions`\n3. Replace `redis.NewClient(options)` by `consul.NewClient(options)`\n\nEverything else works the same way. `interactWithStore()` is completely unaffected.\n\n### Examples\n\nSee the [examples](https://github.com/philippgille/gokv/tree/master/examples) directory for more code examples.\n\nProject status\n--------------\n\n\u003e Note: `gokv`'s API is not stable yet and is under active development. Upcoming releases are likely to contain breaking changes as long as the version is `v0.x.y`. This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html) and all notable changes to this project are documented in [CHANGELOG.md](https://github.com/philippgille/gokv/blob/master/CHANGELOG.md).\n\nPlanned interface methods until `v1.0.0`:\n\n- `List(any) error` / `GetAll(any) error` or similar\n\nThe interface might even change until `v1.0.0`. For example one consideration is to change `Get(string, any) (bool, error)` to `Get(string, any) error` (no boolean return value anymore), with the `error` being something like `gokv.ErrNotFound // \"Key-value pair not found\"` to fulfill the additional role of indicating that the key-value pair wasn't found. But at the moment we prefer the current method signature.\n\nAlso, more interfaces might be added. For example so that there's a `SimpleStore` and an `AdvancedStore`, with the first one containing only the basic methods and the latter one with advanced features such as key-value pair lifetimes (deletion of key-value pairs after a given time), notification of value changes via Go channels etc. But currently the focus is simplicity, see [Design decisions](#design-decisions).\n\nMotivation\n----------\n\nWhen creating a package you want the package to be usable by as many developers as possible. Let's look at a specific example: You want to create a paywall middleware for the Gin web framework. You need some database to store state. You can't use a Go map, because its data is not persisted across web service restarts. You can't use an embedded DB like bbolt, BadgerDB or SQLite, because that would restrict the web service to one instance, but nowadays every web service is designed with high horizontal scalability in mind. If you use Redis, MongoDB or PostgreSQL though, you would force the package user (the developer who creates the actual web service with Gin and your middleware) to run and administrate the server, even if she might never have used it before and doesn't know how to configure them for high performance and security.\n\nAny decision for a specific database would limit the package's usability.\n\nOne solution would be a custom interface where you would leave the implementation to the package user. But that would require the developer to dive into the details of the Go package of the chosen key-value store. And if the developer wants to switch the store, or maybe use one for local testing and another for production, she would need to write *multiple* implementations.\n\n`gokv` is the solution for these problems. Package *creators* use the `gokv.Store` interface as parameter and can call its methods within their code, leaving the decision which actual store to use to the package user. Package *users* pick one of the implementations, for example `github.com/philippgille/gokv/redis` for Redis and pass the `redis.Client` created by `redis.NewClient(...)` as parameter. Package users can also develop their own implementations if they need to.\n\n`gokv` doesn't just have to be used to satisfy some `gokv.Store` parameter. It can of course also be used by application / web service developers who just don't want to dive into the sometimes complicated usage of some key-value store packages.\n\nInitially it was developed as `storage` package within the project [ln-paywall](https://github.com/philippgille/ln-paywall) to provide the users of ln-paywall with multiple storage options, but at some point it made sense to turn it into a repository of its own.\n\nBefore doing so I examined existing Go packages with a similar purpose (see [Related projects](#related-projects)), but none of them fit my needs. They either had too few implementations, or they didn't automatically marshal / unmarshal passed structs, or the interface had too many methods, making the project seem too complex to maintain and extend, proven by some that were abandoned or forked (splitting the community with it).\n\nDesign decisions\n----------------\n\n- `gokv` is primarily an abstraction for **key-value stores**, not caches, so there's no need for cache eviction and timeouts.\n  - It's still possible to have cache eviction. In some cases you can configure it on the server, or in case of Memcached it's even the default. Or you can have an implementation-specific `Option` that configures the key-value store client to set a timeout on some key-value pair when storing it in the server. But this should be implementation-specific and not be part of the interface methods, which would require *every* implementation to support cache eviction.\n- The package should be usable without having to write additional code, so structs should be (un-)marshalled automatically, without having to implement `MarshalJSON()` / `GobEncode()` and `UnmarshalJSON()` / `GobDecode()` first. It's still possible to implement these methods to customize the (un-)marshalling, for example to include unexported fields, or for higher performance (because the `encoding/json` / `encoding/gob` package doesn't have to use reflection).\n- It should be easy to create your own store implementations, as well as to review and maintain the code of this repository, so there should be as few interface methods as possible, but still enough so that functions taking the `gokv.Store` interface as parameter can do everything that's usually required when working with a key-value store. For example, a boolean return value for the `Delete` method that indicates whether a value was actually deleted (because it was previously present) can be useful, but isn't a must-have, and also it would require some `Store` implementations to implement the check by themselves (because the existing libraries don't support it), which would unnecessarily decrease performance for those who don't need it. Or as another example, a `Watch(key string) (\u003c-chan Notification, error)` method that sends notifications via a Go channel when the value of a given key changes is nice to have for a few use cases, but in most cases it's not required.\n  - \u003e Note: In the future we might add another interface, so that there's one for the basic operations and one for advanced uses.\n- Similar projects name the structs that are implementations of the store interface according to the backing store, for example `boltdb.BoltDB`, but this leads to so called \"stuttering\" that's discouraged when writing idiomatic Go. That's why `gokv` uses for example `bbolt.Store` and `syncmap.Store`. For easier differentiation between embedded DBs and DBs that have a client and a server component though, the first ones are called `Store` and the latter ones are called `Client`, for example `redis.Client`.\n- All errors are implementation-specific. We could introduce a `gokv.StoreError` type and define some constants like a `SetError` or something more specific like a `TimeoutError`, but non-specific errors don't help the package user, and specific errors would make it very hard to create and especially maintain a `gokv.Store` implementation. You would need to know exactly in which cases the package (that the implementation uses) returns errors, what the errors mean (to \"translate\" them) and keep up with changes and additions of errors in the package. So instead, errors are just forwarded. For example, if you use the `dynamodb` package, the returned errors will be errors from the `\"github.com/aws/aws-sdk-go` package.\n- Keep the terminology of used packages. This might be controversial, because an abstraction / wrapper *unifies* the interface of the used packages. But:\n    1. Naming is hard. If one used package for an embedded database uses `Path` and another `Directory`, then how should be name the option for the database directory? Maybe `Folder`, to add to the confusion? Also, some users might already have used the packages we use directly and they would wonder about the \"new\" variable name which has the same meaning.  \n    Using the packages' variable names spares us the need to come up with unified, understandable variable names without alienating users who already used the packages we use directly.\n    2. Only few users are going to switch back and forth between `gokv.Store` implementations, so most user won't even notice the differences in variable names.\n- Each `gokv` implementation is a Go module. This differs from repositories that contain a single Go module with many subpackages, but has the huge advantage that if you only want to work with the Redis client for example, the `go get` will only fetch the Redis dependencies and not the huge amount of dependencies that are used across the whole repository.\n\nRelated projects\n----------------\n\n- [libkv](https://github.com/docker/libkv)\n  - Uses `[]byte` as value, no automatic (un-)marshalling of structs\n  - No support for Redis, BadgerDB, Go map, MongoDB, AWS DynamoDB, Memcached, MySQL, ...\n  - Not actively maintained anymore (3 direct commits + 1 merged PR in the last 10+ months, as of 2018-10-13)\n- [valkeyrie](https://github.com/abronan/valkeyrie)\n  - Fork of libkv\n  - Same disadvantage: Uses `[]byte` as value, no automatic (un-)marshalling of structs\n  - No support for BadgerDB, Go map, MongoDB, AWS DynamoDB, Memcached, MySQL, ...\n- [gokvstores](https://github.com/ulule/gokvstores)\n  - Only supports Redis and local in-memory cache\n  - Not actively maintained anymore (4 direct commits + 1 merged PR in the last 10+ months, as of 2018-10-13)\n  - 13 stars (as of 2018-10-13)\n- [gokv](https://github.com/gokv)\n  - Requires a `json.Marshaler` / `json.Unmarshaler` as parameter, so you always need to explicitly implement their methods for your structs, and also you can't use gob or other formats for (un-)marshaling.\n  - No support for Consul, etcd, bbolt / Bolt, BadgerDB, MongoDB, AWS DynamoDB, Memcached, MySQL, ...\n  - Separate repo for each implementation, which has advantages and disadvantages\n  - No releases (makes it harder to use with package managers like dep)\n  - 2-7 stars (depending on the repository, as of 2018-10-13)\n\nOthers:\n\n- [gladkikhartem/gokv](https://github.com/gladkikhartem/gokv): No `Delete()` method, no Redis, embedded DBs etc., no Git tags / releases, no stars (as of 2018-11-28)\n- [bradberger/gokv](https://github.com/bradberger/gokv): Not maintained (no commits in the last 22 months), no Redis, Consul etc., no Git tags / releases, 1 star (as of 2018-11-28)\n  - This package inspired me to implement something similar to its `Codec`.\n- [ppacher/gokv](https://github.com/ppacher/gokv): Not maintained (no commits in the last 22 months), no Redis, embedded DBs etc., no automatic (un-)marshalling, 1 star (as of 2018-11-28)\n  - Nice CLI!\n- [kapitan-k/gokvstore](https://github.com/kapitan-k/gokvstore): Not actively maintained (no commits in the last 10+ months), RocksDB only, requires cgo, no automatic (un-)marshalling, no Git tags/ releases, 1 star (as of 2018-11-28)\n\nLicense\n-------\n\n`gokv` is licensed under the [Mozilla Public License Version 2.0](https://www.mozilla.org/en-US/MPL/2.0/).\n\n- [FAQ](https://www.mozilla.org/en-US/MPL/2.0/FAQ/)\n- [Summary 1](https://choosealicense.com/licenses/mpl-2.0/)\n- [Summary 2](https://tldrlegal.com/license/mozilla-public-license-2.0-(mpl-2))\n\nDependencies might be licensed under other licenses.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphilippgille%2Fgokv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphilippgille%2Fgokv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphilippgille%2Fgokv/lists"}