FlowStack
Easy Customer Data Modeling

Thu Jun 01 2017 23:14:13 GMT+0200 (CEST), Administrator

Customer Data Modeling Made Easy

In this article we will dig a little deeper into data modeling of the FlowStack profile. We will try to keep it simple and include some examples which could easily be converted into your real world needs.

The intended audience for this article is familiar with terms like REST and JSON. If such terms scare you off, don't worry - head on to our previous article instead - What does a customer look like.

We hope to inspire developers, integrators and business developers to create awesome plugins, integrations and even standalone products using our profile api.

The Profile as a BaaS

The profile is what you are calling a lead, a customer, a contact or a subscriber. You can create, manipulate and query profiles in FlowStack using the API, effectively using it as a backend as a service.

Data Modeling

A profile, although advertised as “schema-less”, needs a schema for validation and allowing UI (and the rest of the platform) to know which fields are available, their type etc.

Let’s assume we would only like to store the following information on profiles: email, name and interests.

The schema could look like this:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Profile",
    "type": "object",
    "properties": {
        "email": {
            "type": "string",
            "description": "Email"
        },
        "name": {
            "type": "string",
            "description": "Name"
        },
        "interests": {
            "type": "array",
            "uniqueItems": true,
            "items": {
                "type": "string"
            }
        }
    }
}

With the above schema we could store a profile looking like this:

{
    "email": "rune@awesomecompany.com",
    "name": "Rune Viem",
    "interests": [
        "Hunting",
        "Reading"
    ]
}

A more complex (and interesting) schema could be created by extending the previous to add support for storing bought items (e.g. from a web shop) on the profile

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Profile",
    "type": "object",
    "properties": {
        "email": {
            "type": "string",
            "description": "Email"
        },
        "name": {
            "type": "string",
            "description": "Name"
        },
        "interests": {
            "type": "array",
            "uniqueItems": true,
            "items": {
                "type": "string"

            }
        },
        "transactions": {
            "type": "array",
            "items": {
                "type": "object",
                "title": "Transaction",
                "properties": {
                    "TransactionId": {
                        "type": "string"
                    },
                    "TransactionDate": {
                        "type": "string"
                    },
                    "TransactionItems": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "title": "Item",
                            "properties": {
                                "name": {
                                    "type": "string"
                                },
                                "price": {
                                    "type": "float"
                                },
                                "currency": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Let's assume the profile from the previous example bought a MacBook Pro and an iPhone from the web shop

{
    "email": "rune@awesomecompany.com",
    "name": "Rune Viem",
    "interests": [
        "Hunting",
        "Reading"
    ],
    "transactions": [{
        "TransactionId": "1110012",
        "TransactionDate": "2016-08-24 22:53:00",
        "TransactionItems": [{
            "name": "Macbook Pro",
            "price": 9995.00,
            "currency": "DKK"
        }, {
            "name": "iPhone 6",
            "price": 4995.00,
            "currency": "DKK"
        }]
    }]
}

Nested properties are cool - when you can handle them
REST

FlowStack provides a REST API through the http methods GET, POST, PUT and DELETE for manipulating profiles.

Conventions

GET retrieves profiles or specific profile

DELETE deletes profile at end point

PUT replaces profile. Partial updates can NOT be done with PUT.

POST is used for create and partial updates

Examples

For simplicity's sake the system properties (e.g. createdAt and updatedAt) are not shown in the examples.

The profile schema for the examples defines a profile as having an email address, a name and transactions. A transaction has a property for telling which store (Store) the transaction was made, a property for the sales representative responsible for the transaction (Sales Contact) and the products (transactionlines) bought. The products are defined by a name (Product name) and a color (Color). Please bear with us, it's a rather simple schema - otherwise this article would be extremely long. By now you should already know enough to model your own.

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Profile",
    "type": "object",
    "properties": {
        "email": {
            "type": "string",
            "description": "Email"
        },
        "name": {
            "type": "string",
            "description": "Name"
        },
        "transactions": {
            "type": "array",
            "items": {
                "type": "object",
                "title": "Transaction",
                "properties": {
                    "Store": {
                        "type": "string"
                    },
                    "Sales Contact": {
                        "type": "string"
                    },
                    "transactionlines": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "title": "Item",
                            "properties": {
                                "Product name": {
                                    "type": "string"
                                },
                                "Color": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Assume we have following resource at /profile/someid

{
    "id": "someid",
    "name": "Rune Viem"
}

PUT /profile/someid

{

    "email": "rune@awesomecompany.com"

}

results in

{
    "id": "someid",
    "email": "rune@awesomecompany.com"
}

Resource has been REPLACED

To achieve a resource looking like this

{
    "id": "someid",
    "name": "Rune Viem",
    "email": "rune@awesomecompany.com"
}

You need to either provide all properties (could mean you need to do a GET to retrieve those properties and values) and send via PUT e.g.

PUT /profile/someid

{
    "name": "Rune Viem",
    "email": "rune@awesomecompany.com"
}

or do a partial update via POST

POST /profile/someid

{
    "email": "rune@awesomecompany.com"
}

Assuming the profile looked like this before

{
    "id": "someid",
    "name": "Rune Viem"
}

which will leave existing properties as is if they are not targeted for update (included in the payload)

Adding to a subresource (nested property on the profile) e.g. Transactions via POST

POST /profile/someid/transactions

{
    "Store": "CPH",
    "Sales Contact": "Simon Galschiøt",
    "transactionlines": [
        {
            "Product name": "Pillow",
            "Color": "Green"
        }
    ]
}

could result in

{
    "id": "someid",
    "name": "Rune Viem",
    "email": "rune@awesomecompany.com",
    "transactions": [
        {
            "id": "sometransactionid",
            "Store": "CPH",
            "Sales Contact": "Simon Galschiøt",
            "transactionlines": [
                {
                    "id": "somelineid",
                    "Product name": "Pillow",
                    "Color": "Green"
                }
            ]
        }
    ]
}

which could of course also be achieved by using PUT on profile resource containing full profile

PUT /profile/someid

{
    "name": "Rune Viem",
    "email": "rune@awesomecompany.com",
    "transactions": [
        {
            "Store": "CPH",
            "Sales Contact": "Simon Galschiøt",
            "transactionlines": [
                {
                    "Product name": "Pillow",
                    "Color": "Green"
                }
            ]
        }
    ]
}

Adding another transaction line under sometransactionid

POST /profile/someid/transactions/sometransactionid/transactionlines

{
    "Product Name": "Couch",
    "Color": "Red"
}

which would result in

{
    "id": "someid",
    "name": "Rune Viem",
    "email": "rune@awesomecompany.com",
    "transactions": [
        {
            "id": "sometransactionid",
            "Store": "CPH",
            "Sales Contact": "Simon Galschiøt",
            "transactionlines": [
                {
                    "id": "somelineid",
                    "Product name": "Pillow",
                    "Color": "Green"
                },
                {
                    "id": "someotherlineid",
                    "Product name": "Couch",
                    "Color": "Red"
                }
            ]
        }
    ]
}

Updating a sub resource (transactionline) using PUT

PUT /profile/someid/transactions/sometransactionid/transactionlines/somelineid

{
    "Color": "Yellow"
}

results in the profile looking like this

{
    "id": "someid",
    "name": "Rune Viem",
    "email": "rune@awesomecompany.com",
    "transactions": [
        {
            "id": "sometransactionid",
            "Store": "CPH",
            "Sales Contact": "Simon Galschiøt",
            "transactionlines": [
                {
                    "id": "somelineid",
                    "Color": "Yellow"
                },
                {
                    "id": "someotherlineid",
                    "Product name": "Couch",
                    "Color": "Red"
                }
            ]
        }
    ]
}

Doing another update on same transactionline

PUT /profile/someid/transactions/sometransactionid/transactionlines/somelineid

{
    "Product": "Pillow",
    "Color": "Yellow"
}

results in the profile looking like this

{
    "id": "someid",
    "name": "Rune Viem",
    "email": "rune@awesomecompany.com",
    "transactions": [
        {
            "id": "sometransactionid",
            "Store": "CPH",
            "Sales Contact": "Simon Galschiøt",
            "transactionlines": [
                {
                    "id": "somelineid",
                    "Product": "Pillow",
                    "Color": "Yellow"
                },
                {
                    "id": "someotherlineid",
                    "Product name": "Couch",
                    "Color": "Red"
                }
            ]
        }
    ]
}

Updating the same transactionline with POST

POST /profile/someid/transactions/sometransactionid/transactionlines/somelineid

{
    "Color": "Red"
}

Result is

{
    "id": "someid",
    "name": "Rune Viem",
    "email": "rune@awesomecompany.com",
    "transactions": [
        {
            "id": "sometransactionid",
            "Store": "CPH",
            "Sales Contact": "Simon Galschiøt",
            "transactionlines": [
                {
                    "id": "somelineid",
                    "Product name": "Pillow",
                    "Color": "Red" // Partial update of this attribute only
                },
                {
                    "id": "someotherlineid",
                    "Product name": "Couch",
                    "Color": "Red"
                }
            ]
        }
    ]
}

Updating a transaction

Using PUT (replaces the whole targeted transaction object/resource)

PUT /profile/someid/transactions/sometransactionid

{
    "Store": "London",
    "Sales Contact": "John Doe",
    "transactionlines": [
        {
            "Product name": "Shoe"
        }
    ]
}

Results in profile looking like

{
    "id": "someid",
    "name": "Rune Viem",
    "email": "rune@awesomecompany.com",
    "transactions": [
        {
            "id": "someothertransactionid",
            "Store": "London",
            "Sales Contact": "John Doe",
            "transactionlines": [
                {
                    "id": "someotherotherlineid",
                    "Product name": "Shoe"
                }
            ]
        }
    ]
}

Doing a POST to same transaction (simple partial update without nested properties)

POST /profile/someid/transactions/sometransactionid

{
    "Sales Contact": "Jane Doe",

}

Results in profile looking like

{
    "id": "someid",
    "name": "Rune Viem",
    "email": "rune@awesomecompany.com",
    "transactions": [
        {
            "id": "someothertransactionid",
            "Store": "London",
            "Sales Contact": "Jane Doe",
            "transactionlines": [
                {
                    "id": "someotherotherlineid",
                    "Product name": "Shoe"
                }
            ]
        }
    ]
}

If a POST to a sub resource includes contents of a nested resource, the nested resource will be replaced as you have explicitly set the contents of the nested resource

E.g.

POST /profile/someid/transactions/sometransactionid

{
    "Sales Contact": "John Doe",
    "transactionlines": [
         {
             "Product name": "Shoe",
             "Color": "Black"
         }
    ]
}

will result in profile looking like this

{
    "id": "someid",
    "name": "Rune Viem",
    "email": "rune@awesomecompany.com",
    "transactions": [
        {
            "id": "someothertransactionid",
            "Store": "London",
            "Sales Contact": "John Doe",
            "transactionlines": [
                {
                    "id": "someotherotherotherlineid", // new resource created (replaced)
                    "Product name": "Shoe",
                    "Color": "Black"
                }
            ]
        }
    ]
}

Using your own id's (actually pretty cool)

FlowStack will generate system id's for profiles when they are created. You have the possibility to set those id's yourself when you create profiles. This could be very convenient for some of you as it eliminates the need for lookup on other field/property before retrieving profile.

Querying (even cooler)

The profile API is not just for retrieving, creating, updating and deleting profiles by id's.

We created a language, SegQL, allowing you to query your profiles collection like you would query a database.

Segmentation and querying profiles will be the topic of a future article.

Here you go

By now you should know the basics of the FlowStack Profile API, which enables you to connect the dots from your various data silos into our Customer Data Platform which would benefit your marketers greatly.

We would love to hear from you, if you have interesting use cases and integrations you would like to discuss.

Visit us at FlowStack and sign up for updates on the development of the Next Gen Marketing Automation Platform.

Knock yourself out: Create - don't just build


Tags

Follow us

Latest blogs
Welcome to TECHNO
Wed Oct 24 2018 15:03:08 GMT+0200 (CEST)
FlowStack Appoints CTO
Mon Sep 03 2018 10:58:20 GMT+0200 (CEST)
Welcome to Hedin Automotive Belgium
Thu Jun 21 2018 14:06:30 GMT+0200 (CEST)
Welcome to Mercedes-Benz CPH
Tue Mar 13 2018 14:42:14 GMT+0100 (CET)
Goritas chooses FlowStack and gets leads and sales
Mon Jan 29 2018 00:00:26 GMT+0100 (CET)