Clojure(script) schema for Experience API 1.0.3. Provides validation of Statements and other xAPI objects.
You can use xapi-schema to validate (and generate) statements in real-time with this demo.
- Add to your project dependencies:
[[com.yetanalytics/xapi-schema "1.3.0"]] - Require in your project:
(nsyour-project.core (:require [xapi-schema.core :as xs]))
(defstatement
{"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(let [json-statement (clj->js statement)]
(xs/validate-statement-data-js json-statement)) ;; => returns the statement(defstatement-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 ednChecking 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 (...All of the subschemata in xapi-schema.spec are valid Clojure Specs:
(nsyour-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"}) ;; => nilYou can use spec’s generation functions to generate conformant statements containing random data:
- Include the
test.checkdependency:[[com.yetanalytics/xapi-schema "1.0.0-alpha2"] [org.clojure/test.check "0.10.0-alpha2"]]
- Include the extra namespaces and generate!
(nsyour-project.core (:require [xapi-schema.spec :as xapispec] [clojure.spec.alpha :as s :include-macrostrue] [clojure.spec.gen.alpha :as sgen :include-macrostrue] clojure.test.check.generators)) (sgen/generate (s/gen::xapispec/statement)) ;; => {"actor" {...
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:
varstatement_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." }}}}';varstatement_json=JSON.parse(s);xapi_schema.core.validate_statement_data_js(statement_str);// => statement JSONxapi_schema.core.validate_statement_data_js(statement_json);// => statement JSON$ make test-clj
$ make test-cljs
$ make ci
Copyright © 2015-2024 Yet Analytics, Inc.
Distributed under the Eclipse Public License, the same as Clojure. See the file LICENSE for details.