Developer Deep Dive: mParticle Sample Apps
Recently, a cross-functional squad of engineers, PMs and designers at mParticle assembled to produce a labor of love––sample applications. These sample apps help developers implement our SDK in Web, iOS, and Android environments and understand the value of mParticle. Here’s the nuts-and-bolts story behind what they built, the technical choices they made while building these apps, and what they learned along the way.
Engineers, imagine this scenario. Your colleague on the product team sends you a Slack message on a Monday morning. “Hey!” She says, “We just got a new vendor through procurement.” The words begin to tie a knot in your stomach, as if your partner just texted you saying “we need to talk.” At the bottom of the chat window Slack tells you your colleague is typing.... and the knot tightens. “It’s an analytics platform that will give us more visibility into user journeys,” her message says. “Do you think we can have it integrated on Web, iOS and Android by the end of the month?”
You know your colleague is just doing her job. After all, the product folks do need to see where users are getting stuck in the new onboarding flow, and this tool should help them out. But you dread what this means for you and your fellow developers. The last time you had to implement a vendor SDK, it was like finding your way out of a cluttered room while wearing a blindfold. You cringe at the thought of once again having to piece together the mental model behind a new API and tie this system into your own codebase without breaking anything, all the while thinking I still have to build that new feature, and this integration is getting in my way.
This situation is one with which engineers at mParticle are intimately familiar. While these days our developers build rather than implement SDKs, many of our engineers know what it’s like to be on the other side of the table singing the “New SDK Blues.” It’s this first-hand experience that drove us to make our latest investment in the mParticle developer experience: fully-functioning sample eCommerce applications for Web, iOS, and Android, implemented end-to-end with our SDKs.
These apps provide you with a playground for experimenting with our SDK, and learning how event collection works with mParticle. They highlight working examples of our events implemented on common user actions like page views, product customizations, add/remove from cart buttons, and checkout buttons, among others. In many cases, you may find that you’re able to copy these events directly into your own application, and only make light modifications to meet the needs of your specific use case.
In the video below, Alex Sapountzis and Peter Jenkins, the mParticle engineers who headed up the Web and iOS sample app development respectively, discuss their own experiences implementing vendor SDKs and why they developed the sample apps.
“We want to quickly give you a mental map of what happens both in your app and our system when you implement mParticle, without requiring you to go through a lot of trial and error,” says Matt Bernier, Senior Product Manager of Developer Experience at mParticle. “Since these apps show you our SDKs running in exactly the context you’re looking for, there’s no guesswork. This means you can finish your implementation and move on to the next project more quickly.”
Looking under the hood of the sample apps
If you’re an mParticle customer, you can see these apps in action and refer to the code directly as you learn more about our process of building them. Here’s how you can run the app locally:
Note: You’ll need access to an mParticle workspace to generate an API key.
- Clone the sample apps repo
- Install package dependencies using npm install
- Navigate to Setup > Inputs in your mParticle workspace
- Select the Web platform, and generate/copy your API key
- In the root of this project, rename .env.sample to .env
- Update the REACT_APP_MPARTICLE_API_KEY environment variable with with your mParticle Web API Key
- Run the project using npm start
Not currently an mParticle customer? Our Accelerator Program is an opportunity for qualified startups to receive up to one year of complimentary access to mParticle.
Not too DRY: How we showcased our SDK by keeping application code simple
Above all else, the sample apps team wanted these products to serve as teaching tools for engineers to learn our SDKs and understand best practices for implementing event collection with mParticle. This objective informed many of the technical choices behind the sample apps, from the tools and frameworks used to build them, to the coding conventions used throughout the projects.
Relatability was the main reason why Alex Sapountzis decided to use React as the framework in which to build the web sample app. React is the most popular frontend framework in the world, and is used to build applications ranging from eCommerce sites to streaming platforms. It’s therefore a safe bet that most web developers who would be implementing the mParticle Web SDK would not have to learn React before being able to get value out of this sample app. When it came to deciding on the React design patterns to use, Alex tried to strike a balance by favoring relatively new ‘built-in’ features, such as React Hooks and Context Providers versus Redux, a third-party library which is a widely-known standard architecture, but can be very overwhelming and complex to ultimately deliver a clearer learning experience to the user.
For example, using custom hooks has been a trend within the React community for quite some time. Using these entails creating your own functions that leverage common React hooks for the purpose of sharing stateful logic between components. Alex felt that using this approach in the sample apps would have gotten in the way of understanding how our SDK is working, and for this reason he opted to stick with using vanilla hooks like useEffect.
“If I was building this as a package that someone would use in their project I may have done things a little differently,” Alex says, “but being that this is an educational tool, I didn’t want someone to have to worry about what React is doing––I wanted them to see what mParticle is doing in a React app.”
Exploring the components of the web app, you’ll see several examples in which useEffect is used to both collect the attributes that will be forwarded with mParticle events, and fire off the events themselves. Here is one such usage of useEffect on the ProductDetailPage component:
useEffect(() => {
// Generates a Product View Detail Event to signal that a customer
// viewed the product details, potentially leading to an 'Add to Cart' Event
if (product) {
// Generate an mParticle Product Object before sending any eCommerce Events
const mParticleProduct: mParticle.Product = getMPProduct(product);
// Fire a single eCommerce Product View Detail Event for this product page
mParticle.eCommerce.logProductAction(
mParticle.ProductActionType.ViewDetail,
mParticleProduct,
);
}
// If you re-render and the product changes,
// this will re-fire a new Product View Detail Event
}, [product]);
Using the vanilla React hook in instances like this makes it much easier to understand the mParticle SDK than if this logic were packaged into separate functions throughout different modules. Also, you may notice that this is a rather comment-heavy code sample. The sample app developers took the time to clearly comment the code surrounding the use of our SDK––both where event calls take place, and throughout the logic that supports event collection. Here’s another example from the same component showing how comments help give you the complete context of how to use our SDK in real life scenarios, and leave nothing up to guesswork:
// It is recommended to use mParticle.createProduct when using our
// eCommerce logging functions to generate events so that you can
// be sure to include all of our data points properly
const getMPProduct = (_product: Product): mParticle.Product => {
const { label, id, price } = _product;
// When passing attributes into mParticle, it's best to not include
// undefined or null values
const attributes: mParticle.SDKEventAttrs = {};
if (color) {
attributes.color = color;
}
if (size) {
attributes.size = size;
}
// In this example we are not fulling handling multiple brands,
// categories and other use cases for a fully fledged e-Commerce
// application. As such, we are passing undefined for many of these
// attributes to highlight cases where you want may need some
// parameters but not all of them.
return mParticle.eCommerce.createProduct(
label,
id,
price,
parseInt(quantity, 10),
undefined, // Variant: used for single variants.
// Use Custom ATtributes for multiple variants like
// in this use case
undefined, // Category
undefined, // Brand
undefined, // Position
undefined, // Coupon Code
attributes,
);
};
Dogfooding our own SDKs and features and leveraging our own products
While the primary purpose of these sample apps is to help our customers easily implement our SDK and realize value from their data, we have also seen great internal value from these apps as a means of testing and improving––or “dogfooding”––our own SDKs and customer-facing features.
Bug hunting in the wilds of TypeScript
For example, building the web sample app allowed us to uncover some edge cases that arise when using our core web SDK within a React project with TypeScript as an npm package. In some cases, the interplay between these three particular technologies resulted in a race condition in which our SDK wouldn’t always be initialized when an event was called. While our core SDK already contained logic to deal with this, certain code within React’s packages broke these checks and caused an unusual cascade to occur. After noticing this issue, Alex went on a bug hunt with fellow JavaScript API guru Rob Ing. The two bushwhacked through the stack trace, fixed the issue, and released patches to our core SDK.
Using our own data planning features
Inconsistencies at the data collection stage are one of the biggest causes of data quality issues further down the pipeline. mParticle’s data planning tools and features are designed to help engineers and other data stakeholders align on a data plan, implement this plan accurately, and identify errors in real time. When we built these sample apps, we wanted to practice what we preach by using our own data planning tools to maintain consistency with how events and attributes are named, structured, and collected across these three platforms.
Our engineers and PMs set up a dedicated mParticle workspace for the sample apps project, and used our user interface to create and generate data plans. Once the events were implemented in all three apps and we were sending events from the SDKs to mParticle, we used Live Stream to check for misalignments between collected and expected data, and Live Stream’s error messaging to easily track down the source of the errors. Using these features made the process of creating data plans, implementing event collection, and ensuring cross-platform consistency much smoother. Our own data planning features were a significant help in the creation of the sample apps, and we plan to continue using the sample apps to test and improve our data planning features.
What does the future hold?
By reducing the learning curve with our SDK, speeding up the implementation time, and decreasing the time-to-value of your data, these sample apps can deliver far-reaching value to engineering teams working with mParticle. The fact that we’ve shipped our MLP (“Minimum Loveable Project,” a term our PM Matt Bernier has coined) marks the beginning, not the end, of our work on improving these resources.
“I think this is definitely something that we’re going to continue to invest in and improve over time,” says Peter Jenkins, “from adding additional comments to always keeping it up to date with changes we make to the SDK.” Additionally, we also intend to continue using these apps as a means of testing and improving not only our SDK and API features, but our entire suite of products and features. In forthcoming iterations of the web sample app, for instance, we plan to integrate our developer tools including Smartype and Linting. In other words, these sample apps will be, as Peter Jenkins puts it, “An evergreen source of documentation for exactly how to use our SDK that you can actually run.”