New GoodData Model API

Jiri Tobolka

If you are integrating GoodData into your application and need to customize the logical data model (LDM - read more about data modeling) based on external factors we are creating a new API just for you.

This Model API is designed to simplify the programmatic creation and update of the logical data model. We will allow you to get a snapshot of the current state of the model and update the model to the desired state.

Using the new API makes your life easier by

  • Abstracting from a specific order of operations you need to perform with MAQL
  • Freeing you from the need to specify low-level details
  • Allowing you to get the current state of the model in one call

Nowadays your only option to create a model is to execute a MAQL DDL script. For a simple model from our HR example here: Data model from our HR example as seen in LDM Modeler in CloudConnect

The MAQL required to create this example model is:

CREATE DATASET {dataset.salary} VISUAL(TITLE "Salary");
CREATE DATASET {dataset.employee} VISUAL(TITLE "Employee");
CREATE DATASET {dataset.department} VISUAL(TITLE "Department");
INCLUDE TEMPLATE "URN:GOODDATA:DATE" MODIFY (IDENTIFIER "salary", TITLE "Salary");
CREATE ATTRIBUTE {attr.salary.salary} VISUAL(TITLE "Salary") AS KEYS {f_salary.id} FULLSET;
ALTER DATASET {dataset.salary} ADD {attr.salary.salary};
ALTER ATTRIBUTE {attr.salary.salary} ADD LABELS {label.salary.salary} VISUAL(TITLE "Salary") AS {f_salary.nm_salary};
CREATE ATTRIBUTE {attr.department.department} VISUAL(TITLE "Department") AS KEYS {f_department.id} FULLSET;
ALTER DATASET {dataset.department} ADD {attr.department.department};
ALTER ATTRIBUTE {attr.department.department} ADD LABELS {label.department.department.name} VISUAL(TITLE "Name") AS {f_department.nm_name};
ALTER ATTRIBUTE {attr.department.department} ADD LABELS {label.department.department} VISUAL(TITLE "Department") AS {f_department.nm_department};
CREATE ATTRIBUTE {attr.employee.employee} VISUAL(TITLE "Employee") AS KEYS {f_employee.id} FULLSET;
ALTER DATASET {dataset.employee} ADD {attr.employee.employee};
ALTER ATTRIBUTE {attr.employee.employee} ADD LABELS {label.employee.employee.firstname} VISUAL(TITLE "Firstname") AS {f_employee.nm_firstname};
ALTER ATTRIBUTE {attr.employee.employee} ADD LABELS {label.employee.employee.lastname} VISUAL(TITLE "Lastname") AS {f_employee.nm_lastname};
ALTER ATTRIBUTE {attr.employee.employee} ADD LABELS {label.employee.employee} VISUAL(TITLE "Employee") AS {f_employee.nm_employee};
CREATE FACT {fact.salary.payment} VISUAL(TITLE "Payment") AS {f_salary.f_payment};
ALTER DATASET {dataset.salary} ADD {fact.salary.payment};
ALTER ATTRIBUTE {salary.date} ADD KEYS {f_salary.dt_salary_id};
ALTER ATTRIBUTE {attr.employee.employee} ADD KEYS {f_salary.employee_id};
ALTER ATTRIBUTE {attr.department.department} ADD KEYS {f_employee.department_id};
SYNCHRONIZE {dataset.salary}, {dataset.employee}, {dataset.department} PRESERVE DATA;

Contrast this with the new API. All you would need to produce is just a simple JSON. For the model above it would look like this:

    {
        "projectModel": {
            "datasets": [
                {
                    "dataset": {
                        "identifier": "dataset.employee",
                        "title": "Employee",
                        "anchor": {
                            "attribute": {
                                "identifier": "attr.employee.employee",
                                "title": "Employee",
                                "folder": "Employee",
                                "labels": [
                                    {
                                        "label": {
                                            "identifier": "label.employee.employee",
                                            "title": "Employee"
                                        }
                                    },
                                    {
                                        "label": {
                                            "identifier": "label.employee.employee.firstname",
                                            "title": "Firstname"
                                        }
                                    },
                                    {
                                        "label": {
                                            "identifier": "label.employee.employee.lastname",
                                            "title": "Lastname"
                                        }
                                    }
                                ]
                            }
                        },
                        "references": ["dataset.department"]
                    }
                },
                {
                    "dataset": {
                        "identifier": "dataset.department",
                        "title": "Department",
                        "anchor": {
                            "attribute": {
                                "identifier": "attr.department.department",
                                "title": "Department",
                                "labels": [
                                    {
                                        "label": {
                                            "identifier": "label.department.department",
                                            "title": "Department"
                                        }
                                    }
                                ]
                            }
                        }
                    }
                },
                {
                    "dataset": {
                        "identifier": "dataset.salary",
                        "title": "Salary",
                        "anchor": {
                            "attribute": {
                                "identifier": "attr.salary.salary",
                                "title": "Salary",
                                "folder": "Salary",
                                "labels": [
                                    {
                                        "label": {
                                            "identifier": "label.salary.salary",
                                            "title": "Salary"
                                        }
                                    }
                                ]
                            }
                        },
                        "facts": [
                            {
                                "fact": {
                                    "identifier": "fact.salary.payment",
                                    "title": "Payment",
                                    "folder": "Salary"
                                }
                            }
                        ],
                        "references": ["dataset.employee", "salarypaid"]
                    }
                }
            ],
            "dateDimensions": [
                {
                    "dateDimension": {
                        "name": "salarypaid",
                        "title": "Salary"
                    }
                }
            ]
        }
    }

We are currently implementing the API. The first version should be ready before end of the year. See the drafted specification of the API.

We are excited to have you use it and to provide feedback once available!


About The Author

Jiri Tobolka Jiri Tobolka works as Developer Evangelist at GoodData and helps people use and build on the top of the GoodData Platform. He is using GoodData since the 2009. In the free time, Jiri enjoys action sports like kiteboarding or skiing.

Twitter @jirtob   Email jiri.tobolka@gooddata.com

Dev's Newsletter

Subscribe Now