SCHEMATA

Table of Contents

Next:   [Contents][Index]

Top


Next: , Previous: , Up: Top   [Contents][Index]

1 Introduction

Generic purpose schema library for serialization and validation of data.

This library is used by CL-REST-SERVER for API serialization and validation.

It features:


Next: , Previous: , Up: Top   [Contents][Index]

2 Installation

With Quicklisp:

  (ql:quickload "schemata")

Next: , Previous: , Up: Top   [Contents][Index]

3 Usage

3.1 Schema definition

Use DEFSCHEMAfor defining schemas.

Schema example:

  (schemata:defschema customer
      (object "customer"
               ((id string :external-name "id" :accessor
                    customer-id :documentation "customer id")
                (number string :external-name "number" :required nil
                                :accessor customer-nr :documentation
                        "customer number")
                (name string :external-name "name" :accessor
                      customer-name :documentation "customer name")
                (address-1 string :external-name "address1"
                                   :required nil :documentation
                           "customer first address")
                (address-2 string :external-name "address2"
                                   :required nil :documentation
                           "customer second address")
                (postal-code string :external-name "postalcode"
                                     :required nil :documentation
                             "postal code")
                (postal-area string :external-name "postalarea"
                                     :required nil :documentation
                             "postal area")
                (country string :external-name "country" :required nil 
                         :documentation "country code")
                (phone string :external-name "phone" :required nil
                               :documentation "phone")
                (fax string :external-name "fax" :required nil
                             :documentation "fax")
                (email string :external-name "email" :required nil
                               :documentation "email"))
               (:documentation "customer data fetched")))

3.2 Validation using schemas

Use VALIDATE-WITH-SCHEMA.

3.3 Serialization using schemas

Via generic-serializer library.

Use SERIALIZE-WITH-SCHEMA.

  (with-output-to-string (s)
      (gs:with-serializer-output s
          (gs:with-serializer :json
             (serialize-with-schema *schema* user))))
  (with-output-to-string (s)
    (gs:with-serializer-output s
      (gs:with-serializer :json
        (serialize-with-schema
         (find-schema 'user-schema) *user*))))

3.4 Unserialization using schemas

Use UNSERIALIZE-WITH-SCHEMA.

  (unserialize-with-schema
     (find-schema 'user-schema)
     (json:decode-json-from-string data)
     :json)

3.5 Patch and updates

See PATCH-WITH-SCHEMAand POPULATE-WITH-SCHEMA.


Next: , Previous: , Up: Top   [Contents][Index]

4 Schema types

4.1 Type schemas

Schemas can be built from Common Lisp types:

SCHEMATA> (defparameter *s* (schema string))
*S*
SCHEMATA> *s*
#<TYPE-SCHEMA STRING {1006FBBD13}>
SCHEMATA> (validate-with-schema *s* "22")
NIL
SCHEMATA> (validate-with-schema *s* 22 :error-p nil)
#<VALIDATION-ERROR "~s is not of type: ~a" {100152EB13}>

4.2 Object schema

Object schemas are built using the syntax: (object name attributes options). Attributes are specified as: (attribute-name attribute-type &rest options).

The attribute-type is parsed as a schema.

Possible attribute options are: ‘required‘, ‘required-message‘, ‘default‘, ‘accessor‘, ‘writer‘, ‘reader‘, ‘parser‘, ‘validator‘, ‘add-validator‘, ‘formatter‘, ‘external-name‘, ‘serializer‘, ‘unserializer‘, ‘slot‘.

Example:

SCHEMATA> (schema (object person
                          ((name string)
                           (age integer :required nil))))
#<OBJECT-SCHEMA {1001843543}>

4.3 List schemas

4.3.1 list-of

Schema for lists with elements of certain type/schema.

Syntax: (list-of list-element-schema)

Examples:

  (schema (list-of string))
  (schema (list-of (or string number)))
SCHEMATA> (defparameter *s* (schema (list-of integer)))
*S*
SCHEMATA> (validate-with-schema *s* '(1 2 "foo"))
; Evaluation aborted on #<SCHEMATA:VALIDATION-ERROR "~s is not of type: ~a" {1006ECA323}>.
SCHEMATA> (validate-with-schema *s* '(1 2 3))
NIL

4.3.2 list

Schema for list with all its elements specified with schemas.

Syntax: (list &rest schemas)

Examples:

  (schema (list string number boolean))

4.3.3 alist-of

Schema for association lists with certain type of keys and values.

Syntax: (alist-of (key-schema . value-schema))

Examples:

  (schema (alist-of (keyword . string)))

4.3.4 alist

Schema for association lists with certain keys and values.

Syntax: (alist association-list &rest options)

where association-list is a list of conses with key and schema.

Options can be :required, :optional and :allow-other-keys.

Examples:

  (schema (alist ((:x . string)(:y . number))))
  (schema (alist ((:x . string)(:y . number)) :optional (:y)))

4.3.5 plist-of

Schema for property lists with certain type of keys and values.

Syntax: (plist-of key-schema value-schema)

Examples:

  (schema (plist-of keyword string))

4.3.6 plist

Schema for property lists with certain keys and values.

Syntax: (plist property-list &rest options)

where property-list specifies the schemas for the keys.

Options can be :required, :optional and :allow-other-keys.

Examples:

  (schema (plist (:x string :y number)))
  (schema (plist (:x string :y number) :optional (:y)))

4.4 HASH-TABLE schemas

4.4.1 hash-table-of

Schema for hash-tables with certain type of keys and values.

Syntax: (hash-table-of key-schema value-schema)

Examples:

  (schema (hash-table-of keyword string))

4.4.2 hash-table

Schema for property lists with certain keys and values.

Syntax: (hash-table property-list &rest options)

where property-list specifies the schemas for the keys and values.

Options can be :required, :optional and :allow-other-keys, and other initargs that are passed to MAKE-HASH-TABLE.

Examples:

  (schema (hash-table (:x string :y number)))
  (schema (hash-table (:x string :y number) :optional (:y)))

4.5 CONS schema

Schema for CONSes.

Syntax: (cons car-schema cdr-schema)

Examples:

  (schema (cons symbol string))

4.6 AND and OR schemas

4.6.1 or

Schemas disjunction.

Syntax: (or &rest schemas)

Example:

  (schema (or string symbol))

4.6.2 and

Schemas conjunction.

Syntax: (and &rest schemas)

Example:

  (schema (and integer (satisfies evenp)))

4.7 Schema references

Defined schemas can be referenced via either ‘(schema schema-name)‘ or ‘(ref schema-name)‘ (they are identical).

Example:

SCHEMATA> (defschema person
            (object person
                    ((name string))))
#<OBJECT-SCHEMA {1006F8A813}>
SCHEMATA> (defparameter *list-of-person* (schema (list-of (ref person))))
*LIST-OF-PERSON*
SCHEMATA> *list-of-person*
#<LIST-SCHEMA {1006F8C2A3}>
SCHEMATA> (parse-with-schema *list-of-person* '((("name" . "Mariano")) (("name" . "Peter"))))
(((NAME . "Mariano")) ((NAME . "Peter")))
SCHEMATA> (validate-with-schema *list-of-person* '((("name" . 22)) (("name" . "Peter"))))
; processing (DEFMETHOD SCHEMA-VALIDATE ...); Evaluation aborted on #<SB-PCL::NO-APPLICABLE-METHOD-ERROR {1008018513}>.
SCHEMATA> (validate-with-schema *list-of-person* '((("name" . 22)) (("name" . "Peter"))))
; Evaluation aborted on #<SCHEMATA:VALIDATION-ERROR "~s is not of type: ~a" {10082EB883}>.
SCHEMATA> (validate-with-schema *list-of-person* '((("name" . "Mariano")) (("name" . "Peter"))))
NIL
SCHEMATA> (validate-with-schema *list-of-person* '((("names" . "Mariano")) (("name" . "Peter"))))
; Evaluation aborted on #<SCHEMATA:VALIDATION-ERROR "Attributes not part of schema: ~a" {1008CD3DD3}>.

5 SATISFIES-SCHEMA type

Schemata integrates with the Lisp type system via the SATISFIES-SCHEMA type. Schemas can be thought as types over data. Defined schemas can be checked using TYPEP and CHECK-TYPE with the type ‘(satisfies-schema schema-name)‘.

Example:

SCHEMATA> (defschema string-schema string)
#<TYPE-SCHEMA STRING {10019DA8B3}>
SCHEMATA> (typep "foo" '(satisfies-schema string-schema))
T
SCHEMATA> (typep 22 '(satisfies-schema string-schema))
NIL
SCHEMATA> (let ((x "foo"))
            (check-type x (satisfies-schema string-schema))
            x)
"foo"

6 SCHEMA-CLASS metaclass

SCHEMA-CLASS classes get an schema attached.

Example:

SCHEMATA> (def-schema-class person ()
            ((name :type string :initarg :name)
             (age :type integer :required nil :initarg :age)))
#<SCHEMA-CLASS SCHEMATA::PERSON>

SCHEMATA> (validate-with-schema (find-class 'person) '(("name" . "Mariano") ("age" . 22)))
NIL

SCHEMATA> (validate-with-schema (find-class 'person) '(("name" . "Mariano") ("age" . 'asdf)) :error-p nil)
#<VALIDATION-ERROR 'ASDF is not of type: INTEGER {100109F833}>

SCHEMATA> (generic-serializer:with-serializer :json
            (generic-serializer:serialize (make-instance 'person :name "Mariano" :age 44)))
{"name":"Mariano","age":44}

Next: , Previous: , Up: Top   [Contents][Index]

7 Data generation

Schemata can generate random data from schemas. It uses check-it library generators for that.

Load schemata-generators system.

Then call check-it:generate with a schema object.

Example:

  (defschema person
      (object person
              ((name string)
               (age integer :required nil)
               (friend (ref person) :required nil))))
  (generate (find-schema 'person))

can generate:

((NAME . "21p7E0w8")
 (FRIEND (NAME . "hD39Dwo")
  (FRIEND (NAME . "QFC67xg206") (AGE . 4)
   (FRIEND (NAME . "bRtUL1z51")
    (FRIEND (NAME . "0")
     (FRIEND (NAME . "ddB57idmh32C4T") (AGE . 1)
      (FRIEND (NAME . "eNKzc") (AGE . 8))))))))

For more control over the generation, attach a generator to schemas via :generator initarg.


Next: , Previous: , Up: Top   [Contents][Index]

8 Reference


Up: Reference   [Contents][Index]

8.1 SCHEMATA package

PACKAGE: SCHEMATA

External definitions

Macros

Macro: SCHEMATA:SCHEMA (schema-def)

Wrapper macro for schema definitions.

Macro: SCHEMATA:DEFSCHEMA (name schema)

Register SCHEMA under NAME. The schema can then be accessed via FIND-SCHEMA.

Macro: SCHEMATA:DEF-SCHEMA-CLASS (name direct-superclasses direct-slots &rest options)

Helper macro to define schema classes

Generic functions

Generic-Function: SCHEMATA:SCHEMA-TYPE (sb-pcl::object)
Generic-Function: SCHEMATA:OBJECT-NAME (sb-pcl::object)
Generic-Function: SCHEMATA:OBJECT-CLASS (sb-pcl::object)
Generic-Function: SCHEMATA:SCHEMA-GENERATOR (sb-pcl::object)
Generic-Function: SCHEMATA:ATTRIBUTE-REQUIRED-P (sb-pcl::object)
Generic-Function: SCHEMATA:ATTRIBUTE-ACCESSOR (sb-pcl::object)
Generic-Function: SCHEMATA:ATTRIBUTE-ADD-VALIDATOR (sb-pcl::object)
Generic-Function: SCHEMATA:ATTRIBUTE-EXTERNAL-NAME (sb-pcl::object)
Generic-Function: SCHEMATA:UNSERIALIZE-WITH-SCHEMA (schema data format)
Generic-Function: SCHEMATA:ATTRIBUTE-FORMATTER (sb-pcl::object)
Generic-Function: SCHEMATA:SCHEMA-DOCUMENTATION (sb-pcl::object)
Generic-Function: SCHEMATA:PARSE-WITH-SCHEMA (schema string-or-data)

Parses the string to an association list using the schema

Generic-Function: SCHEMATA:ATTRIBUTE-TYPE (sb-pcl::object)
Generic-Function: SCHEMATA:OBJECT-ATTRIBUTES (sb-pcl::object)
Generic-Function: SCHEMATA:ATTRIBUTE-NAME (sb-pcl::object)
Generic-Function: SCHEMATA:ATTRIBUTE-PARSER (sb-pcl::object)
Generic-Function: SCHEMATA:ATTRIBUTE-VALIDATOR (sb-pcl::object)

Functions

Function: SCHEMATA:ATTRIBUTE-TYPE-NAME (attribute)
Function: SCHEMATA:ATTRIBUTE-READER (attribute)
Function: SCHEMATA:POPULATE-WITH-SCHEMA (schema object data &key exclude)

Populate CLOS objects from data + schema. Attributes members of EXCLUDE parameter are not populated.

Function: SCHEMATA:ATTRIBUTE-OPTIONAL-P (attribute)
Function: SCHEMATA:SCHEMA-CLASS-SCHEMA (schema-class)

Generate a schema using the schema class meta info

Function: SCHEMATA:SERIALIZE-WITH-SCHEMA (schema input &optional (serializer generic-serializer::*serializer*) (stream generic-serializer::*serializer-output*))
Function: SCHEMATA:SCHEMA-SPEC (schema)
Function: SCHEMATA:FIND-OBJECT-ATTRIBUTE (object attribute-name &key (error-p t))
Function: SCHEMATA:PATCH-WITH-SCHEMA (schema object data)

Populate CLOS objects from data + schema. Only populates attributes available in DATA, validating them. Useful for PATCH rest api operations implementations. DATA should be an association list.

Function: SCHEMATA:ATTRIBUTE-WRITER (attribute)
Function: SCHEMATA:VALIDATION-ERROR (message &rest args)
Function: SCHEMATA:FIND-SCHEMA (name &optional (errorp t))

Find a schema definition by name

Function: SCHEMATA:VALIDATE-WITH-SCHEMA (schema data &key (collect-errors *collect-validation-errors*) (error-p *signal-validation-errors*))

Validate input using schema. Useful for validating resource operations posted content (for :post and :put methods). Input can be a string or an association list.

Args: - schema (symbol or schema): The schema - data (alist): The data to validate. - format (keyword): The data format. - collect-errors (boolean): If true, collect all the validation errors. If false, return the first validation error found. Default: true. - error-p (boolean): If true, when validation errors are found, a validation error is signaled. If false, the validation errors are returned as the function result and no error is signaled.

Function: SCHEMATA:GENERATE-SCHEMA-FROM-CLASS (class)

Generate a schema from CLASS, using reflection.

Classes

Class: SCHEMATA:OBJECT-SCHEMA

Class precedence list: object-schema, schema, standard-object, t

Slots:

Class: SCHEMATA:CONS-SCHEMA

Schema for CONSes.

Syntax: (cons car-schema cdr-schema)

Examples:

(schema (cons symbol string))

Class precedence list: cons-schema, schema, standard-object, t

Slots:

Class: SCHEMATA:LIST-OF-SCHEMA

Schema for list with elements of certain type/schema.

Syntax: (list-of schema)

Examples:

(schema (list-of string)) (schema (list-of (or string number)))

Class precedence list: list-of-schema, schema, standard-object, t

Slots:

Class: SCHEMATA:PLIST-OF-SCHEMA

Schema for property lists with certain type of keys and values.

Syntax: (plist-of key-schema value-schema)

Examples:

(schema (plist-of keyword string))

Class precedence list: plist-of-schema, schema, standard-object, t

Slots:

Class: SCHEMATA:SCHEMA

Class precedence list: schema, standard-object, t

Slots:

Class: SCHEMATA:ALIST-OF-SCHEMA

Schema for association lists with certain type of keys and values.

Syntax: (alist-of (key-schema . value-schema))

Examples:

(schema (alist-of (keyword . string)))

Class precedence list: alist-of-schema, schema, standard-object, t

Slots:

Class: SCHEMATA:PLIST-SCHEMA

Schema for property lists with certain keys and values.

Syntax: (plist property-list &rest options)

where property-list specifies the schemas for the keys.

Options can be :required, :optional and :allow-other-keys.

Examples:

(schema (plist (:x string :y number))) (schema (plist (:x string :y number) :optional (:y)))

Class precedence list: plist-schema, schema, standard-object, t

Slots:

Class: SCHEMATA:LIST-SCHEMA

Schema for lists.

Syntax: (list &rest schemas)

Examples:

(schema (list string number)) (schema (list symbol number boolean))

Data matches when it is a list of the same size and the list schemas match. For instance, for the schema: (list symbol number symbol), ’(foo 33 bar) matches, but ’(foo 33) does not.

Class precedence list: list-schema, schema, standard-object, t

Slots:

Class: SCHEMATA:SCHEMA-REFERENCE-SCHEMA

Class precedence list: schema-reference-schema, schema, standard-object, t

Slots:

Class: SCHEMATA:ALIST-SCHEMA

Schema for association lists with certain keys and values.

Syntax: (alist association-list &rest options)

where association-list is a list of conses with key and schema.

Options can be :required, :optional and :allow-other-keys.

Examples:

(schema (alist ((:x . string)(:y . number)))) (schema (alist ((:x . string)(:y . number)) :optional (:y)))

Class precedence list: alist-schema, schema, standard-object, t

Slots:

Class: SCHEMATA:SCHEMA-CLASS

Metaclass for schema objects

Class precedence list: schema-class, standard-class, class, specializer, metaobject, standard-object, t

Slots:

Class: SCHEMATA:SCHEMA-OBJECT

Class precedence list: schema-object, standard-object, t

Class: SCHEMATA:TYPE-SCHEMA

Schema for a Common Lisp type.

Syntax: (schema type)

Examples:

(schema string) (schema integer)

Class precedence list: type-schema, schema, standard-object, t

Slots:

Class: SCHEMATA:ATTRIBUTE-PROPERTIES

Class precedence list: attribute-properties, standard-object, t

Slots:

Class: SCHEMATA:VALIDATION-ERROR

Class precedence list: validation-error, error, serious-condition, condition, t

Class: SCHEMATA:ATTRIBUTE

Class precedence list: attribute, schema, attribute-properties, standard-object, t

Slots:


Previous: , Up: Top   [Contents][Index]

9 Index

Jump to:   S  
Index Entry  Section

S
schemata: Top

Jump to:   S  
Jump to:   S  
Index Entry  Section

S
SCHEMATA:ATTRIBUTE-ACCESSOR: SCHEMATA package
SCHEMATA:ATTRIBUTE-ACCESSOR: SCHEMATA package
SCHEMATA:ATTRIBUTE-ADD-VALIDATOR: SCHEMATA package
SCHEMATA:ATTRIBUTE-ADD-VALIDATOR: SCHEMATA package
SCHEMATA:ATTRIBUTE-EXTERNAL-NAME: SCHEMATA package
SCHEMATA:ATTRIBUTE-EXTERNAL-NAME: SCHEMATA package
SCHEMATA:ATTRIBUTE-FORMATTER: SCHEMATA package
SCHEMATA:ATTRIBUTE-FORMATTER: SCHEMATA package
SCHEMATA:ATTRIBUTE-NAME: SCHEMATA package
SCHEMATA:ATTRIBUTE-NAME: SCHEMATA package
SCHEMATA:ATTRIBUTE-OPTIONAL-P: SCHEMATA package
SCHEMATA:ATTRIBUTE-OPTIONAL-P: SCHEMATA package
SCHEMATA:ATTRIBUTE-PARSER: SCHEMATA package
SCHEMATA:ATTRIBUTE-PARSER: SCHEMATA package
SCHEMATA:ATTRIBUTE-READER: SCHEMATA package
SCHEMATA:ATTRIBUTE-READER: SCHEMATA package
SCHEMATA:ATTRIBUTE-REQUIRED-P: SCHEMATA package
SCHEMATA:ATTRIBUTE-REQUIRED-P: SCHEMATA package
SCHEMATA:ATTRIBUTE-TYPE: SCHEMATA package
SCHEMATA:ATTRIBUTE-TYPE: SCHEMATA package
SCHEMATA:ATTRIBUTE-TYPE-NAME: SCHEMATA package
SCHEMATA:ATTRIBUTE-TYPE-NAME: SCHEMATA package
SCHEMATA:ATTRIBUTE-VALIDATOR: SCHEMATA package
SCHEMATA:ATTRIBUTE-VALIDATOR: SCHEMATA package
SCHEMATA:ATTRIBUTE-WRITER: SCHEMATA package
SCHEMATA:ATTRIBUTE-WRITER: SCHEMATA package
SCHEMATA:DEF-SCHEMA-CLASS: SCHEMATA package
SCHEMATA:DEF-SCHEMA-CLASS: SCHEMATA package
SCHEMATA:DEFSCHEMA: SCHEMATA package
SCHEMATA:DEFSCHEMA: SCHEMATA package
SCHEMATA:FIND-OBJECT-ATTRIBUTE: SCHEMATA package
SCHEMATA:FIND-OBJECT-ATTRIBUTE: SCHEMATA package
SCHEMATA:FIND-SCHEMA: SCHEMATA package
SCHEMATA:FIND-SCHEMA: SCHEMATA package
SCHEMATA:GENERATE-SCHEMA-FROM-CLASS: SCHEMATA package
SCHEMATA:GENERATE-SCHEMA-FROM-CLASS: SCHEMATA package
SCHEMATA:OBJECT-ATTRIBUTES: SCHEMATA package
SCHEMATA:OBJECT-ATTRIBUTES: SCHEMATA package
SCHEMATA:OBJECT-CLASS: SCHEMATA package
SCHEMATA:OBJECT-CLASS: SCHEMATA package
SCHEMATA:OBJECT-NAME: SCHEMATA package
SCHEMATA:OBJECT-NAME: SCHEMATA package
SCHEMATA:PARSE-WITH-SCHEMA: SCHEMATA package
SCHEMATA:PARSE-WITH-SCHEMA: SCHEMATA package
SCHEMATA:PATCH-WITH-SCHEMA: SCHEMATA package
SCHEMATA:PATCH-WITH-SCHEMA: SCHEMATA package
SCHEMATA:POPULATE-WITH-SCHEMA: SCHEMATA package
SCHEMATA:POPULATE-WITH-SCHEMA: SCHEMATA package
SCHEMATA:SCHEMA: SCHEMATA package
SCHEMATA:SCHEMA: SCHEMATA package
SCHEMATA:SCHEMA-CLASS-SCHEMA: SCHEMATA package
SCHEMATA:SCHEMA-CLASS-SCHEMA: SCHEMATA package
SCHEMATA:SCHEMA-DOCUMENTATION: SCHEMATA package
SCHEMATA:SCHEMA-DOCUMENTATION: SCHEMATA package
SCHEMATA:SCHEMA-GENERATOR: SCHEMATA package
SCHEMATA:SCHEMA-GENERATOR: SCHEMATA package
SCHEMATA:SCHEMA-SPEC: SCHEMATA package
SCHEMATA:SCHEMA-SPEC: SCHEMATA package
SCHEMATA:SCHEMA-TYPE: SCHEMATA package
SCHEMATA:SCHEMA-TYPE: SCHEMATA package
SCHEMATA:SERIALIZE-WITH-SCHEMA: SCHEMATA package
SCHEMATA:SERIALIZE-WITH-SCHEMA: SCHEMATA package
SCHEMATA:UNSERIALIZE-WITH-SCHEMA: SCHEMATA package
SCHEMATA:UNSERIALIZE-WITH-SCHEMA: SCHEMATA package
SCHEMATA:VALIDATE-WITH-SCHEMA: SCHEMATA package
SCHEMATA:VALIDATE-WITH-SCHEMA: SCHEMATA package
SCHEMATA:VALIDATION-ERROR: SCHEMATA package
SCHEMATA:VALIDATION-ERROR: SCHEMATA package

Jump to:   S