<?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>Forem: Nilkanth Patel</title>
    <description>The latest articles on Forem by Nilkanth Patel (@nilkanthjp).</description>
    <link>https://forem.com/nilkanthjp</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%2F211782%2F17047b0a-1db9-4b08-a1df-42be32cc04d4.jpg</url>
      <title>Forem: Nilkanth Patel</title>
      <link>https://forem.com/nilkanthjp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nilkanthjp"/>
    <language>en</language>
    <item>
      <title>Why GraphQL is the Ideal API Language for Frontend Engineers</title>
      <dc:creator>Nilkanth Patel</dc:creator>
      <pubDate>Fri, 27 Sep 2019 21:44:51 +0000</pubDate>
      <link>https://forem.com/nilkanthjp/why-graphql-is-the-ideal-api-language-for-frontend-engineers-4alm</link>
      <guid>https://forem.com/nilkanthjp/why-graphql-is-the-ideal-api-language-for-frontend-engineers-4alm</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Facebook unveiled GraphQL to the developer community in 2015. What was once an internal research project quickly became the hot new standard for API development. Since then, it has grown tremendously, in terms of usage as well as mindshare—plenty of enterprises have already adopted it for some portion of their backend stack, including &lt;a href="https://developer.github.com/v4/"&gt;Github&lt;/a&gt;, &lt;a href="https://medium.com/paypal-engineering/tagged/graphql"&gt;PayPal&lt;/a&gt;, and &lt;a href="https://medium.com/airbnb-engineering/how-airbnb-is-moving-10x-faster-at-scale-with-graphql-and-apollo-aa4ec92d69e2"&gt;Airbnb&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  What is GraphQL?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://graphql.org/"&gt;GraphQL is a query language for APIs&lt;/a&gt;. It stands in comparison to REST, the most common standard for APIs built today. It allows clients to only fetch the data they need, and makes it easy to map relationships between data types (hence the "graph").&lt;/p&gt;

&lt;p&gt;Developing a GraphQL API &lt;a href="https://graphql.org/learn/"&gt;starts with defining a schema&lt;/a&gt; that describes the data types your API will house, the relationships between those types, and the queries and mutations that allow you to perform common CRUD operations on your data. Consult &lt;a href="https://graphql.org/learn/"&gt;the official documentation for the language&lt;/a&gt; to learn more about syntax and the various ways to implement your own GraphQL API.&lt;/p&gt;

&lt;h1&gt;
  
  
  Recent Trends in Frontend Engineering
&lt;/h1&gt;

&lt;p&gt;Let's first take a look at three of the biggest trends in frontend engineering over the last five years:&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Better Tooling&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The Javascript ecosystem has never been more robust. Since 2015, &lt;a href="http://www.modulecounts.com/"&gt;the number of npm modules has increased by 6x&lt;/a&gt;. While some of this growth stems from the rise of Node.js, a large chunk comes from the proliferation of frontend frameworks. Each of these frameworks comes with a number of tools to help with testing and developer experience.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Typescript&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.businesswire.com/news/home/20190423005225/en/npm-Survey-What%E2%80%99s-New-JavaScript-2019"&gt;A recent survey by npm reported roughly 61% of frontend engineers&lt;/a&gt; &lt;a href="https://javascriptsurvey.com/"&gt;&lt;/a&gt;use Typescript, up by more than 31% from their previous survey. Previously, frontend engineers would discover most of their bugs while running their code in the browser. With static type-checking, many errors are caught much earlier, often even in the IDE while it's being written.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Increased Client-Side Application Logic&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Advancements in internet speed, browsers, and processors mean frontend clients can now perform many of the operations that were previously reserved for the backend.&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphQL's Features Align With These Trends
&lt;/h2&gt;

&lt;p&gt;GraphQL possesses features that enable advancements in each of these three areas. That has allowed it to thrive as the best API language for frontends. &lt;strong&gt;What was once difficult or impossible with REST APIs can be done in minutes with GraphQL.&lt;/strong&gt; Let's take a look at which specific GraphQL features allow for that advancement.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. GraphQL's Schema Introspection ⟶ Better Tooling
&lt;/h3&gt;

&lt;p&gt;Every GraphQL API, regardless of the language or framework it's built with, comes with documentation on every valid request that can be made to, as well as the response the client should expect. This enables developers to build robust tooling customized for the functionality of any GraphQL API.&lt;/p&gt;

&lt;p&gt;The result is tools like &lt;a href="https://github.com/graphql/graphiql"&gt;GraphiQL&lt;/a&gt; and &lt;a href="https://github.com/APIs-guru/graphql-faker"&gt;GraphQL-faker&lt;/a&gt;, two open-source projects that should be staples of any Frontend engineer's toolkit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/graphql/graphiql"&gt;GraphiQL&lt;/a&gt;&lt;/strong&gt; allows you to test queries and generates API docs on the fly. The team at OneGraph has &lt;a href="https://github.com/OneGraph/graphiql-explorer"&gt;even built an explorer&lt;/a&gt; that allows you to interactively write and test queries and mutations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/APIs-guru/graphql-faker"&gt;GraphQL-Faker&lt;/a&gt;&lt;/strong&gt; lets you stand up a mock API service that mimics your actual GraphQL API in minutes. Because introspection allows it to predict the exact shape of the response to any request, it can reliably "fake" them. Just update your API's schema and GraphQL-faker can unblock frontend engineers while the new queries or mutations are implemented on the backend.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nordicapis.com/10-awesome-tools-and-extensions-for-graphql-apis/"&gt;These are just two examples of the dozens of open-source tools&lt;/a&gt; that are only possible because of GraphQL's introspection capabilities.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why is this better than REST?
&lt;/h4&gt;

&lt;p&gt;With REST APIs, the closest analog to GraphiQL is Swagger. But unless the API was built with Swagger's tooling, &lt;a href="https://scotch.io/tutorials/document-your-already-existing-apis-with-swagger"&gt;it's incredibly time consuming to write out the request parameters and response&lt;/a&gt; for every endpoint in the API. GraphiQL will work with any GraphQL API immediately. As for mocking data the way GraphQL-faker does, doing the same for a REST API requires writing out fake responses for every endpoint and continually maintaining them as your API evolves—this can be tedious and error prone.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. GraphQL's Typed Schema ⟶ Great Complement to Typescript
&lt;/h3&gt;

&lt;p&gt;Typescript enables engineering teams to leverage Javascript's speed of development with guardrails that also allow them to move safely.&lt;/p&gt;

&lt;p&gt;GraphQL is the perfect API language to complement Typescript because it is itself strongly typed. That, along with the aforementioned introspection capabilities, means you can use tooling like Apollo Codegen to automatically validate the queries and mutations you're making in your project and autogenerate Typescript interfaces that add types for the expected response.&lt;/p&gt;

&lt;p&gt;Say, for example, you have a GraphQL schema that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Character&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="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Int&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="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&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;character&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Character&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;And in your frontend you've defined the following query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="c"&gt;# src/queries/getCharacter.gql&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GetCharacter&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;character&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;21&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="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;age&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;To automatically generate types for this query, install Apollo's tooling package globally with &lt;code&gt;npm install -g apollo&lt;/code&gt; and run the following command from the root of your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;apollo codegen:generate &lt;span class="nt"&gt;--endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://[GRAPHQL_SERVER] &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;typescript &lt;span class="nt"&gt;--includes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;src/&lt;span class="k"&gt;**&lt;/span&gt;/ &lt;span class="nt"&gt;--tagName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gql &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--addTypename&lt;/span&gt; &lt;span class="nt"&gt;--outputFlat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;src/graphql/types
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will generate a Typescript file at &lt;code&gt;src/graphql/types/getCharacter.ts&lt;/code&gt; that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ====================================================&lt;/span&gt;
&lt;span class="c1"&gt;// GraphQL mutation operation: getCharacter&lt;/span&gt;
&lt;span class="c1"&gt;// ====================================================&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;getCharacter_character&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;__typename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Character&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;getCharacter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;character&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;getCharacter_character&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you're using React to build a &lt;code&gt;&amp;lt;CharacterBio&amp;gt;&lt;/code&gt; component that maps to a &lt;code&gt;Character&lt;/code&gt; GraphQL type, you can use that interface in your React functional component like so (note that this is Typescript, not pure Javascript):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getCharacter_character&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./gen/queries&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CharacterBio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;getCharacter_character&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;character&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;character__name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;character__age&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Your frontend is constantly validating that the queries you intend to make are possible based on the schema of your API, and that you're correctly using the response in your components. &lt;strong&gt;This is incredibly important as teams grow. It means you're never left wondering whether the response from an API request will take the shape you expect.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Why is this better than REST?
&lt;/h4&gt;

&lt;p&gt;This type of compile-time validation is impossible with REST APIs. Even if the API follows OpenAPI standards, there exists no tooling to integrate it this cleanly with Typescript. That means you're left to catch errors only when they appear in your browser's network console.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. GraphQL's Flexible Querying ⟶ Advanced Client-Side Application Logic
&lt;/h3&gt;

&lt;p&gt;One of the traps of REST APIs lead to is designing a backend that aligns exactly with the views required on the frontend. This can be limiting because every time a new view is required, backend teams need to design and implement a new endpoint for the frontend to use.&lt;/p&gt;

&lt;p&gt;For example, let's say you're building a project that needs to store a bunch of &lt;code&gt;task&lt;/code&gt; objects. Each &lt;code&gt;task&lt;/code&gt; has the following fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;summary&lt;/code&gt; - text summary of the task.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;completed&lt;/code&gt; - boolean describing whether or not it's complete.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;assignee&lt;/code&gt; - &lt;code&gt;id&lt;/code&gt; of a single &lt;code&gt;user&lt;/code&gt; object that the task is assigned to.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GraphQL gives frontend engineers the flexibility to fetch only the fields and the data they need to get the job done. It's also designed to make fetching relational data simple. Frontend engineers can harness the querying power of a language like SQL in a syntax that feels like JSON.&lt;/p&gt;

&lt;p&gt;With GraphQL, the schema for this app could look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&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="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&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="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&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="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Task&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;summary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;assignee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&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="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&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;tasks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Int&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="n"&gt;Task&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;This means that you immediately have the power to query tasks with any filter and fetch every task's assignee, along with their name and photo. This can all be done in a single query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="c"&gt;# Fetch all tasks for user 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&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;tasks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&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="n"&gt;summary&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;completed&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="c"&gt;# Fetch all tasks for all users, along with the assignee's name and photo.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&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;tasks&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;summary&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;completed&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;assignee&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="n"&gt;photo&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;&lt;strong&gt;Because the syntax so closely aligns with JSON, it's very easy for any frontend engineer to pick up&lt;/strong&gt;. Pretty powerful stuff, right?&lt;/p&gt;

&lt;h4&gt;
  
  
  Why is this better than REST?
&lt;/h4&gt;

&lt;p&gt;With a REST API, showing all the tasks for a given user is pretty easy. We just need a &lt;code&gt;GET&lt;/code&gt; endpoint that filters based on &lt;code&gt;assignee&lt;/code&gt;, so something like &lt;code&gt;/api/tasks/:userId&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But what if now we wanted to show a stream of all tasks, along with the photos and names of the users they are assigned to. Well, right now our task object only returns the user's &lt;code&gt;id&lt;/code&gt;. We have two options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Augment the response to also include the user's name and photo. These fields may not be used all the time, but will always be fetched.&lt;/li&gt;
&lt;li&gt;Stand up a second endpoint that returns all users, with their &lt;code&gt;id&lt;/code&gt;, photo, and name, and then match the two up on the frontend.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the GraphQL example above, you can accomplish both these tasks with the same query. When you want tasks across all users, omit the &lt;code&gt;userId&lt;/code&gt; input argument. When you only want tasks for one user, include the &lt;code&gt;userId&lt;/code&gt;, but don't fetch the user's name and photo for every task.&lt;/p&gt;

&lt;h1&gt;
  
  
  What Are GraphQL's Shortcomings?
&lt;/h1&gt;

&lt;p&gt;There are certainly tradeoffs to be considered when using GraphQL, especially for frontend engineers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debugging Can Be Difficult
&lt;/h3&gt;

&lt;p&gt;One big difference between REST APIs and GraphQL APIs are that the latter has only one endpoint. All requests are sent to that one endpoint via &lt;code&gt;POST&lt;/code&gt;, and so debugging the responses from an API on the frontend can get frustrating when you just see a bunch of requests like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E4ajSSgo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cq93j4hi62tz63zf8k87.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E4ajSSgo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cq93j4hi62tz63zf8k87.png" alt="Which request is which??"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GraphQL also doesn't employ error codes the way REST APIs do. There is a wide set of predefined HTTP status codes that are designed to cover most issues the frontend might need to handle. That standard protocol makes it easier for a REST API to communicate an error to the frontend. GraphQL, on the other hand, provides very little direction in terms of error handling. The only requirement is that an error is returned with a &lt;code&gt;message&lt;/code&gt; field that provides a &lt;code&gt;string&lt;/code&gt; description of the issue. &lt;a href="https://blog.apollographql.com/full-stack-error-handling-with-graphql-apollo-5c12da407210"&gt;Frontend clients like Apollo help with parsing those errors&lt;/a&gt;, but because there is no communication protocol like with HTTP status codes, every application needs to design one that works for their needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adds Complexity Tradeoff
&lt;/h3&gt;

&lt;p&gt;While GraphQL can make complex queries relatively easy to write, it can also make simple queries a little more difficult to write and parse. Let's say, for example, you wanted to retrieve a specific &lt;code&gt;task&lt;/code&gt; with id &lt;code&gt;1&lt;/code&gt; from your API and log it in the console. With REST, you could write the following fetch call in your frontend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.myapp.com/tasks/1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Pretty straightforward. To do the same thing with GraphQL, you would need to make the following fetch call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.myapp.com/graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`query GetTask($id: Int!) {
    task(id: $id) {
          id
          summary
        assignee {
          name
          photo
        }
      }
    }`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's a fair bit more code for a relatively simple operation. While it may lead to more readable code, it also comes with the overhead of understanding how GraphQL &lt;code&gt;POST&lt;/code&gt; requests must be structured.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Frontend frameworks are in a constant state of flux, but recent developments in the community have paved a path for GraphQL to serve as a great complement to the state-of-the-art frontend tech stack. As with any emerging technology, it comes with a non-trivial learning curve, so it may not always be the best choice. But speaking from experience, once you move to GraphQL, it's tough to go back!&lt;/p&gt;

&lt;p&gt;Want to use a GraphQL API for your next project? &lt;a href="https://midtype.com"&gt;React out to Midtype and we can help!&lt;/a&gt; We help frontend engineers build amazing apps by making it extremely easy to design and deploy GraphQL-based backends.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>graphql</category>
      <category>react</category>
      <category>typescript</category>
    </item>
    <item>
      <title>What's your toolkit for acing Hackathons?</title>
      <dc:creator>Nilkanth Patel</dc:creator>
      <pubDate>Mon, 16 Sep 2019 21:41:40 +0000</pubDate>
      <link>https://forem.com/nilkanthjp/what-s-your-toolkit-for-acing-hackathons-287a</link>
      <guid>https://forem.com/nilkanthjp/what-s-your-toolkit-for-acing-hackathons-287a</guid>
      <description>&lt;p&gt;Like many of the folks in this community, I love hacking. It lets me experiment in a low-pressure environment and learn new technologies without worrying about long-term viability.&lt;/p&gt;

&lt;p&gt;I've spent a lot of time thinking about how I can be a more effective hacker—what tools can I use to expedite the "boring" stuff (infrastructure, auth, backend code to glue together a datastore, etc.) so that I can maximize time spent on the stuff that differentiates my project.&lt;/p&gt;

&lt;p&gt;I'm wondering what tools other people use to get them going and save time during hackathons. Here's my list for context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://firebase.google.com"&gt;Firebase&lt;/a&gt; (auth, NoSQL database)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://reactjs.org/"&gt;React&lt;/a&gt; (frontend framework)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://gatsbyjs.org/"&gt;Gatsby&lt;/a&gt; or &lt;a href="https://github.com/facebook/create-react-app"&gt;Create React App&lt;/a&gt;, depending on how much of my site can be static (boilerplate, frontend dev experience)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://netlify.com"&gt;Netlify&lt;/a&gt; (hosting/deployment, serverless function deployment)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anyone have anything else that they love using?&lt;/p&gt;

</description>
      <category>saas</category>
      <category>beginners</category>
      <category>hackathon</category>
    </item>
    <item>
      <title>Why starting a SaaS business is hard for developers AND non-developers</title>
      <dc:creator>Nilkanth Patel</dc:creator>
      <pubDate>Thu, 22 Aug 2019 19:30:40 +0000</pubDate>
      <link>https://forem.com/nilkanthjp/why-starting-a-saas-business-is-hard-for-developers-and-non-developers-3ao6</link>
      <guid>https://forem.com/nilkanthjp/why-starting-a-saas-business-is-hard-for-developers-and-non-developers-3ao6</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fm86dc6xmg0fxeizgv1uk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fm86dc6xmg0fxeizgv1uk.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Starting a SaaS business is hard.&lt;/p&gt;

&lt;p&gt;If you're a programmer, there's so much to learn about sales and marketing. The coding should be relatively easy (unless it's hard tech), but even then, it can takes weeks of plumbing to put together the basics for your SaaS app.&lt;/p&gt;

&lt;p&gt;If you're not a programmer, I imagine you've got the sales and/or marketing piece down, but without a technical co-founder, you're stuck in deep, deep outsourcing hell.&lt;/p&gt;

&lt;p&gt;My friend Jay and I fit very firmly in the former group. We are devs. He is a backend engineer, I do frontend. We get excited by problems that can be solved with software (really excited), and have a tendency to jump too quickly to writing code. We often overlook the right go-to-market strategy for the product we're imagining. And once the code is written, we find ourselves in a rut. In fact, for our first project, we made 616 real commits to our product before even finding our first 10 customers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fsfk3nzd8459y85j6f6u8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fsfk3nzd8459y85j6f6u8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We made this mistake twice, and then realized a timeless lesson about building product: de-risk your biggest shortcomings first. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://svpg.com/author/marty/" rel="noopener noreferrer"&gt;Marty Cagan's consulting group&lt;/a&gt;, a renowned product think tank in the tech world, accurately describes the challenge that startups face as &lt;a href="https://svpg.com/four-big-risks/" rel="noopener noreferrer"&gt;a combination of four risks&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Value Risk (do you deliver enough value for people to try it?)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Usability Risk (can your users figure out how to use it?)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Feasibility Risk (do you have the technical chops to build it?)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Business Viability Risk (will you make enough money from the product?)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We're good at writing code. We're pretty good at talking to customers and iterating too. And that means we can probably figure out usability and feasibility for most products we work on.&lt;/p&gt;

&lt;p&gt;What we're not great at is marketing and finding a growth channel that will consistently work for us. We're also not great at evaluating how to make the most money off the product. That means we need to start by de-risking the value and business viability of what we're building.&lt;/p&gt;

&lt;p&gt;The best founding teams have members who can answer all of these questions right out of the gate, but that's probably a tall order for the vast majority of startups.&lt;/p&gt;

&lt;p&gt;So instead, we're starting here by understanding how we can generate the most value for our customers first. Pretty meta, but our customers are other people looking to build SaaS products we want to generate that value for other developers (or non-developers) looking to start SaaS businesses themselves.&lt;/p&gt;

&lt;p&gt;We want to help people build and launch SaaS products without sacrificing long-term scalability. We're working on a backend for SaaS that takes minutes to start using (with code or no code—thanks Webflow!), but can last you much longer than Firebase or outsourcing the whole project. Something like this would've helped us spend less time on engineering so that we're de-risking the parts of our business that are most questionable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the hardest part of the SaaS-building process for you? What can we help you with?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>saas</category>
      <category>backend</category>
      <category>nocode</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
