Clojure and DynamoDB with Faraday, Part 2

The story so far

On Part 1 we went over the basic operations - creating a table, checking its status, getting data in and performing a simple retrieval.

We’ll now look into various ways of retrieving items, including querying, scanning, and using projections to get only a few properties.

This assumes you’ve already completed part 1, since we’ll be using the data we added. As a reminder, I’m following the Javascript examples on basic DynamoDB operations, since they are the ones where the data set-up will more closely match Clojure. You may want to follow along for extra explanations and for comparison purposes.

Clojure and DynamoDB with Faraday, Part 1

DynamoDB and Clojure

There are two main options of accessing DynamoDB in Clojure right now - Amazonica, which provides a Clojure client through reflection that’s comprehensive but a direct translation of Amazon’s; and Faraday, which does not take the reflection approach and provides a simpler, more succinct access than one would otherwise get.

Both have a paucity of examples. Amazonica can probably better get away with it since it gets to piggy-back on the AWS examples out there, but Faraday’s tests have been growing and can double as examples.

I started with Faraday, since its more concise API was more appealing and I liked its reasonable defaults. In the process, I’ve added some missing functionality, expanded tests, and noticed that the examples from Amazon’s Getting Started tutorial weren’t fully covered.

Let’s fix that.

ClojureScript performance revisited

Introduction

At the recent Thingmonk conference in London, I got to chatting about Clojure and ClojureScript. It’s an IoT event, so it was to be expected that the topic of performance on devices like the Tessel or Raspberry Pi would come up.

That got me thinking about the piece I wrote back in January about ClojureScript performance for Processing sketches. How much has ClojureScript performance improved since?

Let’s find out.

Use namespaced keywords for events

Introduction

If you’re using re-frame as your pattern for single-page applications in ClojureScript (and why wouldn’t you?), then you are defining your events and handlers using keywords.

These are a prime example of when Clojure’s namespaced keywords come in handy.

cljsbuild configuration for Chrome extensions

The problem

You’ve written your Chrome extension in ClojureScript, whether using Khroma or any other alternative. You have a background script, maybe some content script that gets run on pages, maybe some code for a management UI. Everything’s fine on development, but when you’re ready to release and want to apply some optimizations, everything gets bundled together into a single file. Not only you end up with a larger JS that gets loaded multiple times, but your initialization code starts tripping over each other.

Learning Clojure: Error messages

I started my recent Clojure talk by enumerating the “scary bits” for new users. The two I went into were the fundamentally different semantics, and that the doc strings for the core functions were succinct and exact, but not expansive in use cases.

There was one that I forgot to bring up, though: compiler error messages when there’s a problem with a macro call.

There’s been a lot of chatter on the topic this past week, since Colin Fleming gave a talk at Clojure/Conj on the subject focusing on how to improve them with grammars. The conversation has kept a positive focus on how to fix it, as opposed to piling negativity on the situation (go Clojure community!) but that does not mean we can expect to see a change right away.

I’d like to address how this might affect you if you’re just getting into the language, and what you can do about it.

git flow releases with ClojureScript

While we’re on the topic of Clojure being useful

I use git flow for all my projects. It’s relaxing to know that, even when you’re working solo, you have zero chance of screwing yourself over because - say - you need to make a hotfix but can’t because of a dirty master branch state.

In some projects like khroma I’ll use major/minor version for the release numbers. But in a lot of cases, like this very site, there’s no concept of a major or minor release - you just want to time-stamp each one. I may even need to start several releases a day.

I wrote a small ClojureScript helper to remove the chance of human error.

The Clojure learning curve

I love Clojure.

Once you have tried it and enjoyed its advantages, you just don’t want to go back. But those same qualities that make you love it can make it easy to forget that, for someone who’s first encountering it, Clojure can be a threatening, scary area far outside their comfort zone.

A few weeks ago I gave a talk at the Bucharest Functional Programming Meet Up. The title was Clojure All The Way Down, since my initial plan was to focus on how to program web applications completely in Clojure (both the browser client and back end), and what it brings to the table.

Two things happened as I prepared the talk.

Relevance - Preview release

I’m a tab-aholic

I normally do a search, start opening the tabs that seem interesting, and then as I flip through them, I end up opening even more links on tabs as they seem relevant. Next thing I know I have a huge mess of tabs, and it’s hard to remember which one I’ve read or which one is important.

Relevance is a Chrome plugin I wrote to help manage that.

Respecting early adopters

Perhaps the trickiest thing when developing an open source library is figuring out the balance between changes you feel are necessary, and respecting early adopters.

Take the case of khroma, the ClojureScript library for providing idiomatic access to the Chrome extensions API. It’s very much a work in progress, and I’m developing it to use on an extension of my own. The way I go about it is exposing functions and event handlers mostly as I need them, to avoid getting sidetracked into surfacing functionality for which I don’t have a practical use case right away.

However, when developing something organically, the question then becomes: where do you draw the line between unifying the way the APIs behave after adding functionality, and not breaking things for those very early users?