«

Client API Tutorial

This tutorial introduces the Datomic Client API. You will:

Prerequisites

This tutorial assumes that you have setup Datomic Local and started a REPL with Datomic Local on your classpath, or you have launched a Datomic Cloud system and know how to start a Clojure REPL with the Datomic client API installed.

Create a Client

Using Datomic Local

To interact with Datomic, you must first create a datomic.client.api/client.

In your REPL, execute:

noslide

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

(def cfg {:server-type :datomic-local
          :system "datomic-samples"})

(def client (d/client cfg))

Using Datomic Cloud

To connect to Datomic Cloud, you will need the following information:

  • :region is the AWS region in which you've started Datomic Cloud.
  • :system is your Datomic system's name.
  • :endpoint is your system's client endpoint. Check your CloudFormation outputs for ClientApiGatewayEndpoint.

Use this information to create a client with datomic.client.api/client.

Even though the endpoint is public, client access is securely managed by IAM permissions.

noslide

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

(def cfg {:server-type :cloud
          :region "<your AWS Region>" ;; e.g. us-east-1
          :system "<system name>"
          :creds-profile "<your_aws_profile_if_not_using_the_default>"
          :endpoint "<your endpoint>"})

(def client (d/client cfg))

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

Create a Database

noslide

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

noslide

(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:

noslide

(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"}])

noslide

(d/transact conn {:tx-data movie-schema})
=>
{:db-before ..., 
 :db-after ..., 
 :tx-data [...], ;; data added to the database
 :tempids {}}

You should get back a response as shown above.

Transact Data

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

noslide

(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:

noslide

(d/transact conn {:tx-data first-movies})
=>
{:db-before ... 
 :db-after ...
 :tx-data [...], 
 :tempids {}}

You should see a response similar to the above with different data.

Query

noslide

(def db (d/db conn))  
  • Now create a query for all movie titles:

noslide

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

noslide

(d/q all-titles-q db)
=>
[["Commando"] ["The Goonies"] ["Repo Man"]]

If your database has a large number of movies, it may be prudent to use qseq to return a lazy sequence quickly rather than waiting for the full results to build and return.

Delete a Database (Optional)

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

noslide

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