Writing Specifications

Specifications are used to retrieve information. They describe the shape of the desired facts. You start out by writing a specification function.

Specification Function

A specification function returns j.match. It passes in a template, which is a JSON object describing the type and one predecessor of the desired facts.

function postsByAuthor(author) {
    return j.match({
        type: "Blog.Post",
        author
    });
}

Ensure

Most of the time, a specification function matches a successor of the argument. That is to say that the argument appears as a field of the template.

But sometimes a specification function needs to match a predecessor of the argument. This kind of specification is more commonly used in authorization rules. When you match against a predecessor, you must first ensure that the argument has that predecessor.

function authorOfPost(post) {
    ensure(post).has("author");
    return j.match(post.author);
}

Predicate

A specification function can use suchThat to extend the specification with a predicate. These apply additional conditions.

function publishedPostsByAuthor(author) {
    return j.match({
        type: "Blog.Post",
        author
    }).suchThat(postIsPublished);
}

Pass a conditional function into suchThat.

Conditional Function

A conditional function returns j.exists or j.notExists. Just like a specification function, a conditional function passes in a template. This template is a JSON object describing the type and one predecessor of facts to test for. If any such facts are found, then j.exists evaluates to a true condition.

function postIsPublished(post) {
    return j.exists({
        type: "Blog.Post.Publish",
        post
    });
}

You can combine templates and conditions to describe complex shapes. This diagram illustrates the rules for defining a template function.

specification: ensure ( argument ) .has ( field ) j.match ( template ) predicate predicate: . suchThat ( j.not ( Function that returns a condition ) ) Function that returns a condition condition: j.notExists j.exists ( template ) predicate

Continue With

Retrieving Information