Stashy is a Really simple Key Value store

In my various websites and web applications, I often need to store some things and later retrieve them.

Mostly for this I use a really simple key value store called "Stashy", that I built, oh, decades ago.

Imagine I have a "plain old class object", and I want to save it. It might be an object called "myNewBlogPost".

I will call:

stashy.Save<BlogPost>(myNewBlogPost.Slug, myNewBlogPost);

Later, if I want to load that blog post, I will need to know the key I used, let's say it was "hello-world":

var myNewBlogPost = stashy.Load<BlogPost>("hello-world");

And there's also a method for loading all objects of a given type:

var myBlogPosts = stashy.LoadAll<BlogPost>();

And for deleting a single object:

stashy.Delete<BlogPost>("hello-world");

And that's it!

It's not distributed. It doesn't have a query language. It doesn't have built in caching semantics. It's not even async.

I tell you what it does have: utility. It's bloody useful! I would definitely not consider it for cases with millions of records, but 1000 or under? It's fine! And one less thing to worry about.

The Stashy class is an implementation of the IStashy interface. This makes it easier to test, and helps me with the dependency injection stuff. Mostly it serves to make sure I'm keeping the contract small.

The IStashy interface is just this:

public interface IStashy<K>
{
    void Save<T>(T t, K id);
    T Load<T>(K id);
    IEnumerable<T> LoadAll<T>();
    void Delete<T>(K id);
    K GetNewId<T>();
}

The type K is the type of key you want to use. I usually use strings as my key. But you can use integers or guids, or anything else, if you like.

As I tweeted recently, The heart and soul of my most used key-value store fits in a single tweet. Easily!

I've used a couple of different implementations of this interface over the years, but currently what it does is serialize the object as JSON and then store it in a file named after the key, in a sub-folder named after the type of the object. (I also have a completely in-memory implementation, for testing etc.)

Here's an implementation I use at the moment in one of my projects. It is not glorious beautiful wonderous code, but it is working code that I just... well I just never have to look at it. But I rely on it all the time:

see gist: FileStashy.cs

It's about 100 lines of code, written years ago, and relies on Newtonsoft.Json to turn objects into Json and vice-versa.

(10 years ago my FileStashy used XML, on Windows... Now it's all Json, and runs anywhere that .net core runs. Maybe one day, one special day, we'll all switch to CSV.)

Sometimes I build other stuff on-top of Stashy, such as indexes, for faster lookups, and "revisions", so I can look at old versions of an object. That was easy enough to write (and very fun of course!) but I wouldn't want to do too much with it, or I'd switch to a real key value store... but then get all the headaches that come from those.

Got any crufty little things you've rolled yourself instead of using something "better"?

 

My book "Choose Your First Product" is available now.

It gives you 4 easy steps to find and validate a humble product idea.

Learn more.

(By the way, I read every comment and often respond.)

Your comment, please?

Your Name
Your Url (optional)
Note: I may edit, reuse or delete your comment. Don't be mean.