<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sophie Boulaaouli</title>
    <description>The latest articles on DEV Community by Sophie Boulaaouli (@sophieboulaouli).</description>
    <link>https://dev.to/sophieboulaouli</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F311827%2Ff833dc75-c7c4-4835-b729-f38d7d73984a.jpg</url>
      <title>DEV Community: Sophie Boulaaouli</title>
      <link>https://dev.to/sophieboulaouli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sophieboulaouli"/>
    <language>en</language>
    <item>
      <title>How we started setting up a design system at Escape</title>
      <dc:creator>Sophie Boulaaouli</dc:creator>
      <pubDate>Thu, 19 Jan 2023 15:06:00 +0000</pubDate>
      <link>https://dev.to/sophieboulaouli/how-we-started-setting-up-a-design-system-at-escape-3mme</link>
      <guid>https://dev.to/sophieboulaouli/how-we-started-setting-up-a-design-system-at-escape-3mme</guid>
      <description>&lt;p&gt;As our product expands, and so does our team, we need to have a better workflow. By basing themselves on a single source of truth, designers and developers speak the same language, and everyone can then focus on the essential: the user experience. This source of truth is called the design system, and we will tell you how we put it in place at Escape. But first, a little explanation of what it is exactly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is a design system?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As Dan Mall writes in his article &lt;a href="https://danmall.com/posts/what-is-a-design-system/" rel="noopener noreferrer"&gt;What is a Design system?&lt;/a&gt;, there are a lot of ways to define a design system, for example Alla Kholmatova, &lt;a href="https://www.smashingmagazine.com/design-systems-book/" rel="noopener noreferrer"&gt;Design Systems&lt;/a&gt; said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A set of connected patterns and shared practices, coherently organized to serve the purposes of a digital product.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Andrew Couldwell, &lt;a href="https://designsystemfoundations.com/" rel="noopener noreferrer"&gt;Laying the Foundation&lt;/a&gt; wrote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Design systems bring order and consistency to digital products. They help to protect the brand, elevate the user experience, and increase the speed and efficiency of how we design and build products.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And Marco Suarez, &lt;a href="https://www.designbetter.co/design-systems-handbook" rel="noopener noreferrer"&gt;Design System Handbook&lt;/a&gt; defines it like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A collection of reusable components, guided by clear standards, that can be assembled together to build any number of applications.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even though there is a wide range of design systems, in his article, Dan Mall identifies 6 of them from his own work experience. In my company, we are using the design system he describes as Tools:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tools are some of the most common instances of digital design systems we see. UI kits are great examples.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and a bit of the design system he describes as Process:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Governance lays out who does what and when. So, process and workflow is a really big part of how design systems need to live within an organization.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because we are using &lt;a href="https://www.figma.com/" rel="noopener noreferrer"&gt;Figma&lt;/a&gt; for the design process and &lt;a href="https://storybook.js.org/" rel="noopener noreferrer"&gt;Storybook&lt;/a&gt; for the developers team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do we use it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgtiacg06c9k5196hjgs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgtiacg06c9k5196hjgs.png" alt="Escape Design system design (Figma) and code equivalent (Storybook, CSS, Sass, Windi)&amp;lt;br&amp;gt;
" width="800" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today, we use these five tools to build our design system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In the design process, we use Figma,&lt;/strong&gt; the base that combines all the elements that make up our design system. Indeed, you can find our typographies, colors, spacing measures, icons, and components there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhsm26d4t2m9534z2ee7u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhsm26d4t2m9534z2ee7u.png" alt="Escape design system on Figma&amp;lt;br&amp;gt;
" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In the development process, we use Storybook&lt;/strong&gt; as our UI library where developers can access our coded components previously designed and validated in Figma. Additionally, we use Sass to declare all our colors, fonts, and breakpoints variables as well as CSS to declare semantic variables using a naming convention. Finally, for the utilities we use Windi, which is useful for spacing and the layout.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgyr3615tm74v3qja0acx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgyr3615tm74v3qja0acx.png" alt="Escape design system in the Front-End development&amp;lt;br&amp;gt;
" width="800" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How did we implement it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before implementing our design system, we partially used a UI kit named Creative Tim, but we had a lot of hardcoded values (hexadecimal colors, spacing...). So to create our own design system, we proceeded in 2 steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1- Design system initialization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In a incremental way, we created our color palette with SASS variables in variables.scss file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;red-50&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;#fdefea&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;red-100&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;#fde1d9&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;red-200&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;#fdd4ca&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We initialized CSS semantic variables in theme.scss file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="nt"&gt;--text-badge-danger&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;$red-900&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;--text-badge-success&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;$escape-cyan-600&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;--text-badge-warning&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;$amber-700&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="nt"&gt;Font&lt;/span&gt; &lt;span class="nt"&gt;Family&lt;/span&gt;
  &lt;span class="nt"&gt;--font-family-body&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;font-family-body&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;--font-family-heading&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;font-family-heading&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="nt"&gt;Font&lt;/span&gt; &lt;span class="nt"&gt;size&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="nt"&gt;--font-size-tiny&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;95&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;--font-size-base&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;--font-size-l&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;125&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="nt"&gt;Font&lt;/span&gt; &lt;span class="nt"&gt;weight&lt;/span&gt;
  &lt;span class="nt"&gt;--font-weight-light&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;300&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;--font-weight-normal&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;400&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;--font-weight-medium&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;500&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;--font-weight-semibold&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;600&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;--font-weight-bold&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;700&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our spacing system is based on the font size root. For vertical and horizontal spacing, we set up Windi CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mx-auto my-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"px-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;We use Windi's spacing system&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We set up Storybook to code all our designed components and to reference our default stories with their associated style in app.scss file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flf4syjkwb3frqzuj5nty.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flf4syjkwb3frqzuj5nty.png" alt="default styles" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2- Design system establishment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When the design system was robust enough we removed our old UI kit and replace all hardcoded values with CSS semantic values. 🧹💅&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What did the design system bring us?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Today, it is much easier to maintain the product as each component existing on Figma is named the same way in Storybook and that enhances the workflow between the design and code processes because they use the same vocabulary.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhnhcunf85sr0iqyshf82.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhnhcunf85sr0iqyshf82.png" alt="Same secondary button component in Figma and in Storybook&amp;lt;br&amp;gt;
" width="800" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It enables the designers’ team to be more efficient. Indeed, all the colors and fonts variables are already set up in Figma so it doesn't take long to design components or pages. Besides, components are documented in Figma where they can be easily selected when designing new layouts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qannoz7spe61ng3vyyy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qannoz7spe61ng3vyyy.png" alt="Figma variables that compose the design system" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same process applies to the developers’ team. They can use existing components in Storybook that are necessary to develop the feature without thinking of the components' design or without writing a single line of css.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftpo3gssdbx8ls2hnr1ai.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftpo3gssdbx8ls2hnr1ai.png" alt="Front-End variables that compose the design system&amp;lt;br&amp;gt;
" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Needless to say that when a new component is created, it must be validated by the product team and then be coded into the Storybook so that the developers can use it in the future.&lt;/p&gt;

&lt;p&gt;This design system works well with our process, but we will likely tend to a more integrated and fluid workflow that responds to our organization's needs. As Dan Mall writes in his article:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Design systems as products need to grow organically with the needs of the organizations they serve.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Therefore, design systems as products would fit in perfectly with our desired workflow. According to Dan Mall, this design system can be defined as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A connected, package-managed, version-controlled software product that contains the smallest set of components and guidelines an organization needs to make digital products consistently, efficiently and happily.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To sum up, we passed from almost nothing to a Tools and process design system, but we know that a design system is not something static and will grow organically with our needs. And that's what makes it fascinating working on it.&lt;/p&gt;

</description>
      <category>podcast</category>
    </item>
    <item>
      <title>How to test the performance of your GraphQL applications?</title>
      <dc:creator>Sophie Boulaaouli</dc:creator>
      <pubDate>Thu, 22 Dec 2022 15:30:00 +0000</pubDate>
      <link>https://dev.to/sophieboulaouli/how-to-test-the-performance-of-your-graphql-applications-2e5k</link>
      <guid>https://dev.to/sophieboulaouli/how-to-test-the-performance-of-your-graphql-applications-2e5k</guid>
      <description>&lt;p&gt;&lt;strong&gt;We released a new feature&lt;/strong&gt; in Escape that enables you to &lt;strong&gt;monitor the performance of your GraphQL application.&lt;/strong&gt; Let's discover it!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔎 Performance is at the heart of GraphQL security. But what makes an API perform poorly?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We found that 80% of all GraphQL endpoints scanned by Escape since its inception are vulnerable to Denial of Service (DoS) and Complexity attacks. That's a lot of APIs with performance problems!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxwc382tahjwaqckpo2fu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxwc382tahjwaqckpo2fu.jpg" alt="Escape CEO Tristan Kalos on GraphQL Security Best Practices during the Apidays Paris (December 2022)" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GraphQL being a Query Language with user-supplied queries, an attacker can craft a request requiring a lot of resources for your server to process. All these requests have in common that they use little-known features of GraphQL.&lt;/p&gt;

&lt;p&gt;DoS attacks are made more accessible by a GraphQL feature named aliasing. With GraphQL aliases, an attacker can call a resolver many times in the same query or mutation, bypassing HTTP-based rate limiting. ➡️ &lt;a href="https://escape.tech/blog/graphql-batch-attacks-cause-dos/" rel="noopener noreferrer"&gt;Read more about this vulnerability and its remediations.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another common cause of performance issues is the ability of clients to nest GraphQL queries and even make them deeply recursive. That happens when your graph contains self-referencing objects. (e.g., a user has friends, who also have friends, who also have friends, etc.) Attackers can abuse this feature to cause CPU or memory exhaustion. ➡️ &lt;a href="https://escape.tech/blog/cyclic-queries-and-depth-limit/" rel="noopener noreferrer"&gt;Learn how it works and how you can protect your API here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Performance issues may also result from the infamous "N+1 problem" in GraphQL. For instance, imagine we want to fetch all users' applications' names. The endpoint will fetch all users first, then resolve subsequent applications sequentially to get their names. We, therefore, have 1 request for the users plus N requests for the applications, one for each user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;applications&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the underlying storage of the endpoint is a relational database, logs will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Fetch all users&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Fetch applications for all users, sequentially&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;applications&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;applications&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;applications&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;applications&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last but not least, performance problems may also result from debug queries. As a developer, if you have a huge query that allows you to fetch most of your database, be sure to have at least two types of environments (dev and production), with debug queries disabled in production. We wrote two articles about best practices for the production environment: &lt;a href="https://escape.tech/blog/graphql-error-handling-a-security-pov/" rel="noopener noreferrer"&gt;GraphQL Error Handling Best Practices for Security&lt;/a&gt; and &lt;a href="https://escape.tech/blog/graphql-verbose-error-suggestions/" rel="noopener noreferrer"&gt;When GraphQL Errors become a Security Issue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, let's see about how Escape finds those vulnerabilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛡️ What does Escape do?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;During the scan&lt;/strong&gt;, Escape's scanner sends a custom header (X-Escape-Request-ID) with each request sent to your API endpoint. This lets us know when we sent it and when we received it. We call this &lt;strong&gt;request tracing&lt;/strong&gt;. The scanner keeps track of all responses time and puts the concerning requests in a queue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After the scan,&lt;/strong&gt; we consume the queue synchronously to be sure the flagged requests outline performance problems in your app.&lt;/p&gt;

&lt;p&gt;Let's take a look at the Escape platform for browsing performance issues found during a scan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚙️ How to manage your performance issues?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14hzz4ddor06cuq6aq24.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14hzz4ddor06cuq6aq24.png" alt="Escape platform Performance view" width="800" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the performance issues view of a scan run with Escape's GraphQL Security Scanner, which enables you to detect and fix your performance problem. Escape lists poorly performing queries and associates a severity score depending on the response time. &lt;strong&gt;A response time above 4 seconds is flagged as medium severity and above 10 seconds as high.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can read our &lt;a href="https://escape.tech/docs/security_tests.html#dos" rel="noopener noreferrer"&gt;documentation about DOS&lt;/a&gt; and &lt;a href="https://escape.tech/docs/security_tests.html#complexity" rel="noopener noreferrer"&gt;Complexity&lt;/a&gt; to learn more about security timeout.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjiqluc4i1d7tcw2ehw87.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjiqluc4i1d7tcw2ehw87.png" alt="Performance issues - How to reproduce panel" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can get more details by clicking on a performance vulnerability. For example, in the screenshot above, our scanner found that the debug query took 5 seconds to process, flagging the issue as medium. As a developer, you can see how to reproduce the request by copying the query and trying it yourself.👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fazqatyk3epccxlc4y8vu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fazqatyk3epccxlc4y8vu.png" alt="Transaction_received query request" width="800" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Want to secure your GraphQL application now? Try Escape for free 🚀&lt;/p&gt;

</description>
      <category>gratitude</category>
    </item>
  </channel>
</rss>
