Learn the basics in 30 minutes.


Prerequisites

This tutorial requires you to have a running karma instance ready. More about how tu run karma here.

Default Karma Models

The following concepts constitute the basic building blocks of karma.run.


Tags

When you create a model, you have the possibility to assign a human-readable name to it. This identifier string lives in a default collection, itself tagged as _tag and must be unique. A new karma instance has the preconfigured tags _tag, _model, _expression, _user, _role and _migration which point to the corresponding model.


Model

Models are type definitions. They describe how an object of a certain kind looks. Each model you create gets its own collection to store object of its kind. Thy can be found under the tag _model


Expressions

Expressions are KVM (karma virtual machine) programs represented as data. They follow karma's built-in expression model found under tag _expression. Persistent expressions live in this model's collection.


Users

Contains user which have access to the database. The user model has the tag _user


Roles

Roles are conected to the permission expression for create, read, update, delete. The user model has the tag _role


Migrations

A migration is a small object that binds an expression to two models: from and to. The migration model has tag _migration.


Example Queries:

let's examine some of these default contents now. For the followin examples, we will communicate directly with the API and use the json Codec. We assume that karma runs under the URL http://localhost:8080


First we need to authenticate to the karma instance. We do that with the 'admin' user and your instance secret.


To authenticate, send a POST request to:

URL: http://localhost:8080/auth

Method: POST

Headers:

X-Karma-Codec: json

Body:

{
"username": "admin",
"password": "<your instance secret>"
}

When you authenticate successfully, you receive an HTTP status of 200 OK and a single string (encoded by your codec) as response. This string is your signature. You may now access other endpoints by providing this (base64-encoded) signature as X-Karma-Signature header.


After that we are ready to query against the api. Lets post a Query:

URL: http://localhost:8080/

Method: POST

Headers:

X-Karma-Signature: pupUry8HQFrFv+zfonCA...RCHUOxdEW+6jcOobo5+s=

X-Karma-Codec: json

Body:

[
"all",
[
"tag",
["string", "_tag"]
]
]

For the following examples, we will just show the Query (Body). Make shure to switch to the JSON Format on the right top corner for these examples.

Example:

Query:
"all", "tag", "string", "_tag"
Notes:

yields a list of the mentioned tags.

Example:

Query:
"all", "tag", "string", "_user"
Notes:

yields a list of users. A new karma instance contains only one 'admin' user

CRUD

With the next steps we will create our own model and create, update, read and delete some content.

Example:

Query:
e.create(e.tag(d.string("_model")), f.function(["param"], e.data(m.struct({
  • myString: m.string(),
  • myInt: m.int32(),
  • myBool: m.bool(),
}
)
)
)
)
Result:
[ "RdVuJLdTKaxCcBHo", "eCGXRjxwHUkQnmzC" ]
Notes:

This example persists a new object of the type _model and yields a ref e.g. ["PTmcyzYCwsaoKsjy","NuqdLqlTbjUfSjkf"] to the persisted object

Example:

Query:
e.create(e.tag(d.string("_tag")), f.function(["param"], e.data(d.struct({
  • tag: d.string("myModel"),
  • model: d.expr({
    • scope: "myNewModel",
    }
    )
    ,
}
)
)
)
)
Result:
[ "FMuBhfUuaTIpSYsF", "HsdnBnrjGtkGsxEK" ]
Notes:

It's possible to nest expressions. This example creates the same model as above, and additionally a new _tag called 'myModel' to that model

Example:

Query:
e.get(e.refTo(e.first(e.all(e.tag(d.string("_tag"))))))
Result:
{ "model": [ "RdVuJLdTKaxCcBHo", "FMuBhfUuaTIpSYsF" ], "tag": "_tag" }
Notes:

This example yields the first object of the _tag type. You may get the same result with a shorter query (eg. all(tag(_tag))) but this example is about the get param

Example:

Query:
e.update({
  • ref: e.refTo(e.first(e.all(e.tag(d.string("myModel"))))),
  • value: e.data(d.struct({
    • myString: d.string("my updated string content"),
    • myInt: d.int32(777),
    • myBool: d.bool(false),
    }
    )
    )
    ,
}
)
Result:
[ "XhLaWkGPNTXywfAQ", "kLccoTYVQihppuJy" ]
Notes:

This query is based on the examples in the create expression. Will change the value of the first object of our example model with tag 'myModel'

Example:

Query:
e.delete(e.refTo(e.first(e.all(e.tag(d.string("myModel"))))))
Result:
{ "myBool": false, "myInt": 777, "myString": "my updated string content" }
Notes:

This query is based on the examples in the create expression. Will delete the first object of our example model with tag 'myModel'