<?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: Gareth Kloeden</title>
    <description>The latest articles on DEV Community by Gareth Kloeden (@garethbk).</description>
    <link>https://dev.to/garethbk</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%2F135198%2Fc2a45d93-fded-44ea-ba3a-48f55ab49d17.jpeg</url>
      <title>DEV Community: Gareth Kloeden</title>
      <link>https://dev.to/garethbk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/garethbk"/>
    <language>en</language>
    <item>
      <title>Deploying graphql-yoga with Now 2.0</title>
      <dc:creator>Gareth Kloeden</dc:creator>
      <pubDate>Fri, 08 Feb 2019 20:38:55 +0000</pubDate>
      <link>https://dev.to/garethbk/deploying-graphql-yoga-with-now-20-p0m</link>
      <guid>https://dev.to/garethbk/deploying-graphql-yoga-with-now-20-p0m</guid>
      <description>

&lt;h1&gt;
  
  
  Deploying graphql-yoga with Now 2.0
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/prisma/graphql-yoga"&gt;graphql-yoga&lt;/a&gt; makes it easy to get a lightweight, fully-featured GraphQL server up and running. Zeit's &lt;a href="https://zeit.co/now"&gt;Now&lt;/a&gt; offers a cloud deployment platform that utilizes serverless infrastructure to power your applications. Let's look at how to these can be combined to deploy a GraphQL server that takes advantage of some of Now's features, as well as noting some potential pitfalls.&lt;/p&gt;

&lt;p&gt;This tutorial assumes some familiarity with GraphQL, but it's ok if you've never built a server before, we'll briefly go over the one we're deploying.&lt;/p&gt;

&lt;p&gt;This article grew out of my difficulties porting a server that worked flawlessly on Now 1.0 to Now 2.0, and as such is not really about using serverless with graphql-yoga, rather how you can make a normal graphql-yoga server work with Now 2.0.&lt;/p&gt;

&lt;p&gt;Final code is available for reference here: &lt;a href="https://github.com/garethpbk/graphql-yoga-now/tree/now"&gt;https://github.com/garethpbk/graphql-yoga-now/tree/now&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;If you haven't used Now before, install the &lt;a href="https://zeit.co/download"&gt;Now Desktop&lt;/a&gt; application and register a Now account. Run &lt;code&gt;now -v&lt;/code&gt; to make sure it worked - it'll print a version number (13.1.2 at time of writing).&lt;/p&gt;

&lt;p&gt;We will deploy a very basic &lt;code&gt;graphql-yoga&lt;/code&gt; server that 1) connects to the &lt;a href="https://pokeapi.co/"&gt;PokéAPI&lt;/a&gt; and 2) returns a list of pokemon or some info about a single pokemon. Clone the server repo: &lt;code&gt;git clone https://github.com/garethpbk/graphql-yoga-now.git&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphQL Server
&lt;/h2&gt;

&lt;p&gt;In the cloned directory run &lt;code&gt;yarn&lt;/code&gt; to install dependencies and then &lt;code&gt;yarn start&lt;/code&gt; to, surprise, start the server. Navigate your browser to &lt;a href="http://localhost:4000"&gt;http://localhost:4000&lt;/a&gt; and you should see the &lt;a href="https://github.com/prisma/graphql-playground"&gt;GraphQL Playground&lt;/a&gt; IDE open up. &lt;code&gt;graphl-yoga&lt;/code&gt; includes this awesome tool to explore your server by default.&lt;/p&gt;

&lt;p&gt;In &lt;em&gt;schema.graphql&lt;/em&gt; there are three types: &lt;code&gt;PokemonList&lt;/code&gt; which is made up of &lt;code&gt;ShortPokemon&lt;/code&gt; with just a name and url, and &lt;code&gt;LongPokemon&lt;/code&gt; with more information. The root &lt;code&gt;Query&lt;/code&gt; type registers two resolvers, one to return a list of &lt;code&gt;ShortPokemon&lt;/code&gt; and one to return a single &lt;code&gt;LongPokemon&lt;/code&gt;. Play around in GraphQL Playground with queries like these:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query GET_ALL_POKEMON {
  allPokemon(limit: 30) {
    pokemon {
      name
      url
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query GET_SINGLE_POKEMON {
  pokemon(id: 140) {
    id
    name
    height
    weight
    frontImage
    backImage
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Preparing for Deployment
&lt;/h2&gt;

&lt;p&gt;The exciting part, time to make our pokemon server available to the world. Create a new file at the root of the project called &lt;code&gt;now.json&lt;/code&gt; - this is a configuration file that tells Now how to build our project.&lt;/p&gt;

&lt;p&gt;First specify that you want to use Now 2.0&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "version": 2
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;(Once upon a time Now was a different platform that used a container-based deployment approach; Now 2.0 shifted this drastically to a serverless model. If you try using version 1 on an account that was made after 2.0 came out, you'll see a "please use Now 2.0" message and it'll fail.)&lt;/p&gt;

&lt;p&gt;Next tell Now exactly &lt;em&gt;how&lt;/em&gt; to build the project using the &lt;code&gt;builds&lt;/code&gt; key&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "version": 2,
  "builds": [
    {
      "src": "src/index.js",
      "use": "@now/node-server"
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is where the magic happens. Now "builders" take the code specified in &lt;code&gt;src&lt;/code&gt; and turn it into a serverless "lambda" function.&lt;/p&gt;

&lt;p&gt;Since our server is a Node.js server, we want to use a Node.js builder. Here is a gotcha - Now's documentation recommends using the &lt;code&gt;@now/node&lt;/code&gt; builder for Node.js functions, but because this one isn't written for serverless, the &lt;code&gt;@now/node-server&lt;/code&gt; builder is the one we want.&lt;/p&gt;

&lt;p&gt;The last thing we need are route definitions that tell HTTP requests where to point to&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "version": 2,
  "builds": [
    {
      "src": "src/index.js",
      "use": "@now/node-server"
    }
  ],
  "routes": [
    {
      "src": "./*",
      "dest": "src/index.js
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;All traffic is directed to the endpoint exposed by the server.&lt;/p&gt;

&lt;p&gt;One last thing before we try deploying: create a file called &lt;em&gt;.nowignore&lt;/em&gt; at the root and add node*modules. This tells Now to not directly upload the node_modules folder, as it builds them during deployment itself. It's just like *.gitignore_.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying with Now
&lt;/h2&gt;

&lt;p&gt;Ok, all the pieces are in place, let's do it! Type &lt;code&gt;now&lt;/code&gt; in the terminal and watch as your project is built before your eyes. When it's done you'll see a "Success! Deployment ready" message. Open up the link it gives you and...oh no, what happened? &lt;strong&gt;HTTP ERROR 500&lt;/strong&gt;!?&lt;/p&gt;

&lt;p&gt;If you look at the build log from the &lt;a href="https://zeit.co/dashboard/"&gt;online Now dashboard&lt;/a&gt; you'll see this error message:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: No schema found for path: /var/task/user/src/schema.graphql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In other words, it can't find our schema, and without a schema a GraphQL Server isn't very useful. The issue comes from how the builders change path references, compared to how it works on your computer. Luckily it's an easy fix; open up &lt;em&gt;index.js&lt;/em&gt; and find the server instance:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const server = new GraphQLServer({
  typeDefs: './src/schema.graphql',
  resolvers,
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;All we have to do is change the &lt;code&gt;typeDefs&lt;/code&gt; property from the relative path to one using &lt;code&gt;__dirname&lt;/code&gt;:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const server = new GraphQLServer({
  typeDefs: __dirname + '/schema.graphql',
  resolvers,
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The builders now know where to look for the schema. Run &lt;code&gt;now&lt;/code&gt; again and this time, opening up the link should navigate to the familiar GraphQL Playground interface.&lt;/p&gt;

&lt;p&gt;That's it! Your &lt;code&gt;graphql-yoga&lt;/code&gt; server is now available in the cloud, accessible to anyone with an internet connection. Pretty cool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Environment Variables
&lt;/h2&gt;

&lt;p&gt;As a bonus, let's see how to use environment variables with Now 2.0, for all those API keys and such we'd rather keep secret. Zeit has a package for using &lt;code&gt;process.env&lt;/code&gt; variables locally in development that mirrors how it's done on a Now deployment:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add now-env
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Create a new file called &lt;em&gt;now-secrets.json&lt;/em&gt; at the project root. As an example we'll make the PokéAPI url an environment variable, so add this:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "@pokemon-api-base-url": "https://pokeapi.co/api/v2/pokemon"
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In &lt;em&gt;now.json&lt;/em&gt; add an "env" field, which is where we will specify what's available in &lt;code&gt;process.env&lt;/code&gt;:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "version": 2,
  "builds": [
    {
      "src": "src/index.js",
      "use": "@now/node-server"
    }
  ],
  "routes": [
    {
      "src": "./*",
      "dest": "src/index.js"
    }
  ],
  "env": {
    "API_BASE_URL": "@pokemon-api-base-url"
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Lastly we will use this in the query resolver; open up &lt;em&gt;src/resolvers/query.js&lt;/em&gt; and add &lt;code&gt;require('now-env')&lt;/code&gt; to the top of the file, then replace the two API calls with the environment variable:&lt;/p&gt;

&lt;p&gt;Before:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const allPokemonRes = await axios(`https://pokeapi.co/api/v2/pokemon?limit=${limit}`);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const allPokemonRes = await axios(`${process.env.API_BASE_URL}?limit=${limit}`);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Before:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const pokemonRes = await axios(`https://pokeapi.co/api/v2/pokemon/${id}`);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const pokemonRes = await axios(`${process.env.API_BASE_URL}/${id}`);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;yarn start&lt;/code&gt; and you should see the server working fine locally, with the API url coming from an environment variable now. Note that in a real project you'll probably want to add &lt;em&gt;now-secrets.json&lt;/em&gt; to your &lt;em&gt;.gitignore&lt;/em&gt; list.&lt;/p&gt;

&lt;p&gt;Next add the secret to your Now account:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;now secret add pokemon-api-base-url https://pokeapi.co/api/v2/pokemon
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Type &lt;code&gt;now&lt;/code&gt; one more time, and the server will be deployed using the environment variable. Keep in mind that Now secrets are tied to your &lt;em&gt;account&lt;/em&gt; and not a specific &lt;em&gt;project&lt;/em&gt; or &lt;em&gt;deployment&lt;/em&gt; - I recommend naming your secrets with specifics, e.g. "pokemon-api-base-url" instead of "api-base-url" as the same secret can be used in multiple projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap Up
&lt;/h2&gt;

&lt;p&gt;That concludes this tutorial! The main difficulties I faced in moving a &lt;code&gt;graphql-yoga&lt;/code&gt; server from Now 1.0 to Now 2.0 were understanding how to set up builds, routes, the schema path, and environment variables; hopefully you've now got a handle on how to work with them all.&lt;/p&gt;

&lt;p&gt;Keep an eye out for part 2: a core feature of Now 2.0 is monorepo support, meaning you can configure one &lt;em&gt;now.json&lt;/em&gt; at a project's root that allows for deployment of multiple servers and front-ends (even in different languages!) - I'm planning on following this article up with an example of deploying a front-end for this server in the same repo.&lt;/p&gt;


</description>
      <category>graphql</category>
      <category>now</category>
      <category>node</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
