Client API Tutorial

This tutorial introduces the Datomic Client API. You will

Prerequisites

This tutorial assumes that you:

Create a Database

To interact with Datomic Cloud, you must first specify a system connection, with:

  • :endpoint is the URI where your system can be reached, "http://entry.<system-name>.<region>.datomic.net:8182" where <system-name> is the same as the Stack Name you used to start the CloudFormation Storage Stack. This endpoint is labeled as EndpointAddress in the Cloudformation Output of the compute stack.
  • :region is the AWS region in which you've started Datomic Cloud.
  • :system is the SystemName

First we'll create a client with datomic.client.api/client. We'll use this client as we explore the Datomic below.

In your REPL, execute:

(require '[datomic.client.api :as d])

(def cfg {:server-type :ion
          :region "<your AWS Region>" ;; e.g. us-east-1
          :system "<system-name>"
          :creds-profile "<your_aws_profile_if_not_using_the_default>"
          :endpoint "http://entry.<system-name>.<region>.datomic.net:8182/"
          :proxy-port 8182})

(def client (d/client cfg))

You may need to use a local SSH tunnel port. Adjust the :proxy-port value to your local tunneling port if necessary.

Warnings may occur. Do not be alarmed as they will not affect functionality during this tutorial.

Given a functioning system, you can use the admin API to create a new database with datomic.client.api/create-database.

(d/create-database client {:db-name "movies"})

Now you're ready to connect to your newly created database using dataomic.client.api/connect.

(def conn (d/connect client {:db-name "movies"}))

The next step will be to define some schema for your new database.

Schema defines the set of possible attributes that can be associated with an entity. We'll need to provide 3 attributes: db/ident, db/valueType and db/cardinality. db/doc will also be provided for documentation.

Transact Schema

Now we need to create a schema.

Define the following small schema for a database about movies:

(def movie-schema [{:db/ident :movie/title
                    :db/valueType :db.type/string
                    :db/cardinality :db.cardinality/one
                    :db/doc "The title of the movie"}

                   {:db/ident :movie/genre
                    :db/valueType :db.type/string
                    :db/cardinality :db.cardinality/one
                    :db/doc "The genre of the movie"}

                   {:db/ident :movie/release-year
                    :db/valueType :db.type/long
                    :db/cardinality :db.cardinality/one
                    :db/doc "The year the movie was released in theaters"}])

Now transact the schema using datomic.client.api/transact.

(d/transact conn {:tx-data movie-schema})

You should get back a response like the following:

{:db-before ..., 
 :db-after ..., 
 :tx-data [...], ;; data added to the database
 :tempids {}}

Transact Data

Now you can define some movies to add to the database utilizing the schema we defined earlier:

(def first-movies [{:movie/title "The Goonies"
                    :movie/genre "action/adventure"
                    :movie/release-year 1985}
                   {:movie/title "Commando"
                    :movie/genre "thriller/action"
                    :movie/release-year 1985}
                   {:movie/title "Repo Man"
                    :movie/genre "punk dystopia"
                    :movie/release-year 1984}])

Transact the movies into the database:

(d/transact conn {:tx-data first-movies})

You should see a response similar to:

=> {:db-before ... 
    :db-after ...
    :tx-data [...], 
    :tempids {}}

Query

Get a current value for the database with datomic.client.api/db:

(def db (d/db conn))  

Now create a query for all movie titles:

(def all-titles-q '[:find ?movie-title 
                    :where [_ :movie/title ?movie-title]])

And execute the query with the value of the database using datomic.client.ap/q:

(d/q all-titles-q db)

You should see:

=> [["Commando"] ["The Goonies"] ["Repo Man"]]

Delete a Database

When you are done with this tutorial, you can use datomic.client.api/delete-database to delete the movies database:

(d/delete-database client {:db-name "movies"})