Skip to content

yetanalytics/xapi-schema

Repository files navigation

xapi-schema

https://github.com/yetanalytics/xapi-schema/actions/workflows/main.yml/badge.svg https://img.shields.io/badge/license-Eclipse-blue.svg https://img.shields.io/clojars/v/com.yetanalytics/xapi-schema.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.3.0"]]
        
  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 © 2015-2024 Yet Analytics, Inc.

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

About

Clojure(script) schema for the Experience API

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages