Powering our APIs using attr active DTOs
<p>Helping lay the groundwork for our new company-wide API was exhilarating. In early 2022, I was on the team that developed a proof of concept and established standards for our new <a href="https://developers.klaviyo.com/en/reference/api_overview" rel="noopener ugc nofollow" target="_blank">APIs</a>. Fast forward to today and you’ll find over 150 endpoints spanning 12 product areas processing millions of requests daily. In this post, I’ll dive into one internal aspect of our APIs: Data Transfer Objects (DTOs). I’ll talk about why we chose <a href="https://www.attrs.org/en/stable/" rel="noopener ugc nofollow" target="_blank">attrs</a> and how we use it. I’ll also show how we standardized the API implementation process for our developers including versioning of endpoints.</p>
<p>The API effort was herculean, spanning multiple engineering and product teams. It took discussions, technical design documents, and of course <em>some</em> <a href="https://en.wikipedia.org/wiki/Law_of_triviality" rel="noopener ugc nofollow" target="_blank">bike-shedding</a>! This quote from an early design document captures the vision:</p>
<blockquote>
<p><em>“Klaviyo deserves a long-standing, consistent & flexible API that can serve developers inside and outside of Klaviyo for years to come while minimizing operational overhead for our internal developers and maximizing consistency and usability for our external developers.”</em></p>
</blockquote>
<h1>Setting the scene</h1>
<p>Our API complies with the <a href="https://jsonapi.org/format/" rel="noopener ugc nofollow" target="_blank">JSON:API</a> spec. Chad Furman from the API team wrote a great <a href="https://klaviyo.tech/api-development-what-companies-need-to-know-about-rest-json-api-and-graphql-part-1-aaf77c5e04ad" rel="noopener ugc nofollow" target="_blank">post</a> on why we chose JSON:API and how we use it. Our implementation is in Python, using the <a href="https://www.django-rest-framework.org/" rel="noopener ugc nofollow" target="_blank">Django Rest Framework</a> (DRF). We leverage DRF’s composable and flexible nature to customize its various components in our API.</p>
<p><a href="https://klaviyo.tech/powering-our-apis-using-attr-active-dtos-f88f2177d855">Read More</a></p>