Clojure(script) schema for the Experience API
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
dev-resources/data
dev
doc
resources/xapi_schema/graphql
src/xapi_schema
test/xapi_schema
.dir-locals.el
.gitignore
.travis.yml
LICENSE
Makefile
README.org
build.test.edn
deps.edn
pom.xml

README.org

xapi-schema

https://travis-ci.org/yetanalytics/xapi-schema.svg?branch=master https://jarkeeper.com/yetanalytics/xapi-schema/status.png https://img.shields.io/badge/license-Eclipse-blue.svg https://img.shields.io/clojars/v/com.yetanalytics/xapi-schema.svg

https://badges.gitter.im/Join%20Chat.svg

Clojure(script) schema for Experience API 1.0.3. Provides validation of Statements and other xAPI objects.

Demo

You can use xapi-schema to validate (and generate) statements in real-time with this demo.

Getting Started

  1. Add to your project dependencies:
    [[com.yetanalytics/xapi-schema "1.0.0-alpha19"]]
        
  2. Require in your project:
    (ns your-project.core
      (:require [xapi-schema.core :as xs]))
        

Usage

Clojure(script)

Validate a Statement or Statements in edn

(def statement
  {"id" "fd41c918-b88b-4b20-a0a5-a4c32391aaa0"
   "actor" {"objectType" "Agent"
            "name" "Project Tin Can API"
            "mbox" "mailto:user@example.com"}
   "verb" {"id" "http://example.com/xapi/verbs#sent-a-statement",
           "display" {"en-US" "sent"}}
   "object" {"id" "http://example.com/xapi/activity/simplestatement",
             "definition"
             {"name" {"en-US" "simple statement"}
              "description"
              {"en-US" "A simple Experience API statement. Note that the LRS
                does not need to have any prior information about the Actor (learner), the
                verb, or the Activity/object."}}}})

(xs/validate-statement-data statement) ;; => returns the statement

(xs/validate-statement-data [stmt1 stmt2 stmt3]) ;; => returns the statements

(let [bad-statement (dissoc statement "actor")]
  (xs/validate-statement-data bad-statement))  ;; => throws ExceptionInfo

Validate a Statement from JSON (Clojurescript)

(let [json-statement (clj->js statement)]
  (xs/validate-statement-data-js json-statement)) ;; => returns the statement

Validate a Statement from a JSON string (Clojure(script))

(def statement-str
  "{\"object\":{\"id\":\"http://example.com/xapi/activity/simplestatement\",
  \"definition\":{\"name\":{\"en-US\":\"simple statement\"},\"description\":
  {\"en-US\":\"A simple Experience API statement. Note that the LRS\\n
  does not need to have any prior information about the Actor (learner), the\\n
  verb, or the Activity/object.\"}}},\"verb\":{\"id\":\"http://example.com/xapi
  /verbs#sent-a-statement\",\"display\":{\"en-US\":\"sent\"}},\"id\":\"fd41c918-
  b88b-4b20-a0a5-a4c32391aaa0\",\"actor\":{\"mbox\":\"mailto:user@example.com\"
  ,\"name\":\"Project Tin Can API\",\"objectType\":\"Agent\"}}")

(xs/validate-statement-data statement-str) ;; => returns statement edn

‘Check’ a Statement

Checking a statement will return nil if it is valid, or a map of errors.

(xs/statement-checker statement) ;; => nil
(let [bad-statement (-> statement
                        (dissoc "actor")
                        (assoc "id" 123)]
  (xs/statement-checker bad-statement)))
  ;; => {:cljs.spec.alpha/problems (...

Use SubSchemata

All of the subschemata in xapi-schema.spec are valid Clojure Specs:

(ns your-project.core
  (:require [xapi-schema.core :as xs]
            [xapi-schema.spec :as json]
            [clojure.spec.alpha :as s]))
(s/explain-data ::json/agent {"mbox" "mailto:bob@example.com"}) ;; => nil

Generate Statements

You can use spec’s generation functions to generate conformant statements containing random data:

  1. Include the test.check dependency:
    [[com.yetanalytics/xapi-schema "1.0.0-alpha2"]
     [org.clojure/test.check "0.10.0-alpha2"]]
        
  2. Include the extra namespaces and generate!
    (ns your-project.core
      (:require [xapi-schema.spec :as xapispec]
                [clojure.spec.alpha :as s :include-macros true]
                [clojure.spec.gen.alpha :as sgen :include-macros true]
                 clojure.test.check.generators))
    (sgen/generate (s/gen ::xapispec/statement)) ;; => {"actor" {...
        

Plain ol’ JavaScript

If you want to use validations from JavaScript, first build the js: $ lein do cljx, cljsbuild once release. Then include the generated file, target/js/xapi_schema.js and invoke:

var statement_str = '{"id":"fd41c918-b88b-4b20-a0a5-a4c32391aaa0", "actor":{"objectType": "Agent","name":"Project Tin Can API","mbox":"mailto:user@example.com"},"verb":{"id":"http://example.com/xapi/verbs#sent-a-statement","display":{ "en-US":"sent" }},"object":{"id":"http://example.com/xapi/activity/simplestatement","definition":{"name":{ "en-US":"simple statement" },"description":{ "en-US":"A simple Experience API statement. Note that the LRS does not need to have any prior information about the Actor (learner), the verb, or the Activity/object." }}}}';
var statement_json = JSON.parse(s);
xapi_schema.core.validate_statement_data_js(statement_str); // => statement JSON
xapi_schema.core.validate_statement_data_js(statement_json); // => statement JSON

Testing

Clojure

$ make test-clj

ClojureScript

$ make test-cljs

Both

$ make ci

License

Copyright © 2018 Yet Analytics, Inc.

Distributed under the Eclipse Public License, the same as Clojure. See the file LICENSE for details.