The FDL File
Let's take a closer look at how Causal uses a FDL file to manage features.
Why an FDL File?
The FDL file for a project defines the data to collect and log for front end1 product features. The Causal compiler will use it to:
- Generate a type-safe API that will help you instrument your code with minimal errors
- Automatically populate your data warehouse with the collected data
- Provide an easy-to-use web interface so non-technical members of the team can modify and test the website.
The FDL file is a regular source code file that is designed to be checked into your revision control system with your other source files. This a "code-first" approach, and it makes working with Causal more developer friendly in a couple of ways:
Since the FDL file is checked in with your source, there's never any confusion about which version of your feature data is working with which version of your code. The production schema is defined by the file on the production branch. Causal does not have to resort to complicated and hard to maintain versioning mechanisms to keep data changes in sync.
Your feature definitions also follow your current software engineering practices. Changes to the FDL file can go through your current code review processes, as opposed to being locked away in some web user interface.
Components of a Feature
Let's take a quick look at an example FDL file to highlight some of the important FDL components.
Feature Definition
A new feature definition starts with the feature keyword followed by a name. It also contains blocks of code that represent the arguments, the outputs, and the events of the feature. For the example application, the feature name is RatingBox
"""
Wraps a rating box that we can put on various product pages
to collect ratings from our users
"""
feature RatingBox {
Comments
FDL is based on GraphQL. Like GraphQL, comments appear as strings before the code you want to comment on. These comments then get copied into the generated APIs, so you should use them rather than the #
comment character, which the compiler ignores as they are meant for internal comments. As with GraphQL, single-line strings are surrounded by a single quote, while triple quotes surround multiline strings.
Arguments (args)
The arguments section contains data that is fed from the front end into Causal. Causal supports all GraphQL types except unions. This example show product with a required string value.2
args {
"The product that we are collecting ratings for"
product: String!
}
The example application sends the product information to Causal and displays the product to the application user as follows:
Outputs
The output section is data that Causal returns to the front end. In this case it defines the callToAction, (a.k.a the CTA)
output {
"The text next to the stars that prompts the visitor to rate the product"
callToAction: String! = "Rate this product!"
As with the args section, you have a set of field names and types. However, for output fields you must additionally define a default value.
The default value's primary function is to return meaningful output to our client UIs that request a feature in cases where the server does not know about the field yet. For example, when you are introducing a new feature and haven't checked in your code yet. Or, when you are connected to an impression server running off an older code branch. If you are familiar with Avro it is the exact same concept. For more information on default values and schema migration, see Calling Convention.
Because the CTA is an output, non-technical users can change its value through the Causal web interface without the need to redeploy any code. The example application displays the CTA as follows.
Events
The events section declares events that are necessary to evaluate a product feature. In this case it defines the rating event. The events declared within a feature definition are specific to that feature. Causal will automatically associate these events with the correct feature impression in the data warehouse. This makes it easy to build a machine learning model or do impression by impression analysis to improve a feature.3 4
actionButton: String! = "Send Review"
}
"Occurs each time a rating is collected"
The example application will wire clicks on the stars to the rating event.
Events can also be defined at the session level in cases where there is no associated feature impression that is directly related to the event.
- The term
front end
is used throughout this text, but it could be any client that needs to collect and log product features, such as a back end API or a microservice.↩ String!
is how you define a required string in GraphQL.↩- Causal puts all the data you need to analyse a feature's impression on a single table row. With simple append-only data stores, you'd have to do a bunch of further ETL to get the data into usable format. Causal's tables are usable out of the box.↩
- This structure also means that access the data in a Causal impression table is orders of magnitude faster than in other systems.↩