<?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: Karen White</title>
    <description>The latest articles on DEV Community by Karen White (@karen_pwhite).</description>
    <link>https://dev.to/karen_pwhite</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%2F115747%2F5462a52b-2c72-4dfc-8819-f97e1e0340a1.jpg</url>
      <title>DEV Community: Karen White</title>
      <link>https://dev.to/karen_pwhite</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/karen_pwhite"/>
    <language>en</language>
    <item>
      <title>Why Clean Code is Empathetic Code</title>
      <dc:creator>Karen White</dc:creator>
      <pubDate>Wed, 17 Apr 2019 19:51:15 +0000</pubDate>
      <link>https://dev.to/karen_pwhite/why-clean-code-is-empathetic-code-2lkn</link>
      <guid>https://dev.to/karen_pwhite/why-clean-code-is-empathetic-code-2lkn</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://medium.com/bigcommerce-developer-blog"&gt;BigCommerce Developer Blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The idea for this post started over a beer.&lt;/p&gt;

&lt;p&gt;I was catching up with &lt;a href="https://www.linkedin.com/in/danmurrelljr/"&gt;Dan Murrell&lt;/a&gt;, Software Engineering Team Lead at BigCommerce, at a Friday happy hour when the conversation turned to a recent project Dan was working on. He told me how he had gotten well into development on a project, only to turn around and start over. He had realized that the code had become indecipherable to anyone but himself, and because of that, a course correction was needed. Not just because he didn’t feel like the quality met his standards, but also for the sake of any future engineers that were assigned to the project. He was currently in the process of reworking the project, organizing the code according to a set of guidelines designed to make it easy for other developers understand what the code was doing with minimal ramp up time.&lt;/p&gt;

&lt;p&gt;This idea interested me, because it’s something that developers find themselves on both sides of. At different times, we might be the one who inherits a spaghetti code base — or, whether we want to admit it or not — the one creating it. Dan pointed out that over its lifetime, a project changes hands many times. And each owner has the opportunity to leave things better than they found them, or to create a giant mess that makes future developers curse their name.&lt;/p&gt;

&lt;p&gt;I wanted to find out more about how Dan thinks about writing clean and readable code, so I met up with him again (no beer this time) to dig deeper into what it means to write code with empathy for future programmers.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Life of Its Own
&lt;/h2&gt;

&lt;p&gt;The first thing to understand is that most software has a life far beyond the original developer who created it.&lt;/p&gt;

&lt;p&gt;“The reality is, if you’re doing any kind of software for a company, it’s going to almost certainly last far longer than you expected,” Dan says. But knowing that your code will live on and be passed to multiple owners changes your mindset about the code you write. “Your tendency is to make the code that you’re writing personal, and you put all your experience into it. But you’re not going to be the only person who ever works on this thing.”&lt;/p&gt;

&lt;p&gt;No matter where you work writing software, it’s rare that you have the luxury of designing a solution from the start. Much more often, you’re working with a code base that you’ve inherited: either a legacy code base within your own company or a client whose website has passed through the hands of multiple developers before you. Being on the receiving end of a train wreck of a code base gives you first hand exposure to the consequences of ignoring clean code best practices.&lt;/p&gt;

&lt;p&gt;Dan recalls, “I worked at an agency for five years, and my first project that I worked on was one that had started from scratch at the company, but the original developer had left. He hadn’t been using the greatest practices and then the project passed through three more developers before it came to me. We started adding new feature requests to it, and we had to understand what this thing does, because now we have to add new features that work with what’s already there. And inevitably, we had to rewrite a lot of code, because maybe it was out of date, or didn’t work, or it never worked in the first place. Probably the first year that I was at that company, it was really just orienting myself in this massive code base.”&lt;/p&gt;

&lt;p&gt;Dan spent the next half year refactoring as he added the new features that were needed. And as the code base was cleaned up, new features that had once seemed impossible to build suddenly seemed straightforward.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I had to take a step back and really consider what had happened. The refactoring work we did made that feature now possible. It wasn’t that it was easy to do — it was only easy to do after all the work we put into it.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Good Developers Write Bad Code
&lt;/h2&gt;

&lt;p&gt;If we assume that developers mean well, why is there so much illegible code out there? Are there just that many…bad developers?&lt;/p&gt;

&lt;p&gt;Not at all. The truth is there are a number of factors working against even the most experienced developer. You might be under a tight deadline or building out a proof of concept — that later becomes a permanent solution. And in those cases, writing the most elegant and well-organized code possible might take a back seat to just making it work and getting the project out the door.&lt;/p&gt;

&lt;p&gt;Plus, the idea that you’ll clean up a project later is often wishful thinking.&lt;/p&gt;

&lt;p&gt;“Even an experienced developer has said 1000 times that they will get back to it, but you never get back to it. Sometimes you do, but more often you won’t. So taking care of things on the front end is the important consideration. Once you have self awareness of the amount of time that’s available to work on a thing, or the fact that you’re not going to be always the one working on the thing, you can make better decisions around how you structure your code,” Dan says.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleaning Up Your Act
&lt;/h2&gt;

&lt;p&gt;We can all agree that it’s better to write legible code the first time around than waiting for a future refactor that may never come. But what do we actually mean when we say legible code — and how do you get there? Next, Dan shares a few tips for writing code that will make your project’s future owner thank you.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Practice.
&lt;/h3&gt;

&lt;p&gt;Dan recommends building clean coding skills through bite-sized trainings. “There are practices that you can do, little exercises called &lt;a href="http://codekata.com/"&gt;Code Katas&lt;/a&gt;, that present you a simple problem. It’s something you can do on a lunch break or in 15 minutes, and it gives you a chance to work through a very short, brief problem in a way that you can practice clean code development.”&lt;/p&gt;

&lt;p&gt;Consider it like building a muscle. These practice sessions can help you cultivate the ability to distill your code to its simplest form, and when best practices become second nature, it’s easier to maintain them.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Extract, extract, extract.
&lt;/h3&gt;

&lt;p&gt;One of the biggest wins for code readability is extracting code out into single-use functions. Dan gives an example:&lt;/p&gt;

&lt;p&gt;“Let’s say you write a 20 line function that does four different things. You can extract those four different things into their own separate functions. And when you do that, you’ve accomplished two things: you’ve isolated the individual things into their own containers and you’ve simplified the structure.”&lt;/p&gt;

&lt;p&gt;Multi-purpose functions will always carry more of a cognitive load because the developer trying to decipher the code has to work out that the code is doing four different things. When you extract that out into separate functions, it becomes much easier to read what each piece of code is doing.&lt;/p&gt;

&lt;p&gt;“Maybe your first function stores a setting on the server. And then maybe the second function you extracted uses that setting to make an API call. And then the next function does some kind of reaction based on the results, and so on,” Dan continues. “Those four functions basically read like a book that tells you what I’m doing.” Dan recommends extracting code out until each function has a single responsibility — and that’s it.&lt;/p&gt;

&lt;p&gt;Once you extract everything out into single purpose functions, you can make your project even more readable by pushing those single use functions down to the bottom of your file. “Put them in private functions so they’re not being exposed to the global namespace, and then what you have as your global function is very simple, very clean: a function that calls those four other functions. That makes it very clean and linear at the top of the file, where somebody’s actually going to be reading, especially if the private function names are very descriptive,” Dan says.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If you see a file that’s written that way, then you can almost certainly assume somebody has used clean code practices to extract, extract, extract and leave behind the very deliberate, very specific, easy-to-read things at the top.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3. Use descriptive names.
&lt;/h3&gt;

&lt;p&gt;Naming functions and variables descriptively is a practice that goes a long way toward making your code readable to others. “When you name things well, it self documents what you’re doing. Nobody wants to write documentation — and nobody wants to read it either. But if you if you name the functions and the variables descriptively, that makes it self documenting, and then you can take that whole documentation step out.”&lt;/p&gt;

&lt;p&gt;At one point in time, it was best practice to be as concise as possible with naming conventions to conserve memory. But that’s no longer the case with today’s resource-rich computing.&lt;/p&gt;

&lt;p&gt;“Back in the old days, you would use function names that were like two letters, or variable names like i and j and k. Nowadays, the compiler is going to compile code down, and storage is essentially free. So there’s really no reason to be brief with your function names and your variables when you don’t have to.”&lt;/p&gt;

&lt;p&gt;Dan also prefers the self-documenting approach to comments in the code. “You do need to document any kind of information that somebody who’s going to consume a framework needs to know. If there’s a default to a Boolean, you should document what that’s going to be. But as far as multi line comments that explain just exactly what the code does — I never see that anymore.”&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Leverage your tools
&lt;/h3&gt;

&lt;p&gt;And when all else fails — automate it. Set yourself up for success by leaning on tools that take the guesswork out of clean code.&lt;/p&gt;

&lt;p&gt;Dan says, “I use Xcode, and there are actually tools inside of Xcode that let you refactor things. It can extract methods out of a bigger block of code, put that put it in a new function, and figure out the inputs that need to go into it.”&lt;/p&gt;

&lt;p&gt;Consistency is another factor that contributes to readable code, and linters are a great tool for enforcing style and formatting conventions. But linters are really only helpful if their usage is established early in the project. “Linters are one of the things you want to put in right at the beginning, because it’s going to flag everything that you’re doing that’s not following the standards that you set for that project. If you’re six months into a project and you’ve written 20,000 lines of code, you add a linter at that point…well just set aside your next month, because you’re just going to be fixing compliance issues,” Dan says.&lt;/p&gt;

&lt;p&gt;If you’re inheriting an older project, a linter won’t help you much at that point. But if you’re fortunate enough to be starting a project from day 1, pulling in a linter can do a lot to make your code readable to the next developer assigned to the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coding with Empathy
&lt;/h2&gt;

&lt;p&gt;What really interested me about my conversation with Dan is the idea that this is not just an academic pursuit, writing clean code for clean code’s sake. There’s a human element to making your code simple and readable. Software is written by teams — not by lone geniuses. Coding with empathy means recognizing that other developers will contribute to your code down the line and making your code approachable to others.&lt;/p&gt;

&lt;p&gt;And when you do that, you can begin to create work that goes beyond the individual and begins serving others. Everyone likes recognition, and it’s satisfying to solve a problem in a particularly clever way. But at the end of the day, it’s not just about you — it’s about the quality of the project and the success of all of the other team members, past, present, and future, who also have a stake.&lt;/p&gt;

&lt;p&gt;Dan sums it up:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Don’t write your code to be clever. Don’t try to impress anybody. If you use empathy driven development, where you’re thinking about the next person working on a thing, you’re going to make decisions keeping them in mind. And what it will do is keep your ego in check, and take your ego out of the equation.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Most developers don’t set out to write code that makes sense only to them, but the reality is that there are factors that work against those good intentions. You might be building out a proof of concept or an MVP that you mean to come back and refine later — but later never comes. Or, you might start out as a project’s sole owner, only to move on or expand your team.&lt;/p&gt;

&lt;p&gt;Once you recognize that software has a life far beyond its original creator, you can start to employ clean code practices by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Training up with problem solving exercises&lt;/li&gt;
&lt;li&gt;Extracting functions into single-purpose blocks&lt;/li&gt;
&lt;li&gt;Naming functions and variables descriptively&lt;/li&gt;
&lt;li&gt;Using built-in tools and linters to automate consistency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…and you’ll produce code that doesn’t make life difficult for future developers working on your project. That’s not just coding with empathy, that’s good karma.&lt;/p&gt;

&lt;p&gt;Thanks to Dan Murrell for the insights and the conversation that sparked this post. You can find Dan on Twitter @danimal99 or tweet us @BigCommerceDevs. Cheers! 🍻&lt;/p&gt;

</description>
      <category>bigcommerce</category>
      <category>programming</category>
      <category>career</category>
    </item>
    <item>
      <title>How to Test App Authentication Locally with ngrok</title>
      <dc:creator>Karen White</dc:creator>
      <pubDate>Fri, 18 Jan 2019 22:41:58 +0000</pubDate>
      <link>https://dev.to/karen_pwhite/how-to-test-app-authentication-locally-with-ngrok-4p9h</link>
      <guid>https://dev.to/karen_pwhite/how-to-test-app-authentication-locally-with-ngrok-4p9h</guid>
      <description>

&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://medium.com/bigcommerce-developer-blog"&gt;BigCommerce Developer Blog&lt;/a&gt;, January 5, 2019&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Developing locally makes it fast and easy to test changes as you work, but no network access has its disadvantages. You might run into situations where you need a publicly accessible URL while you’re still in the development phase. Maybe you want to show your work to a colleague or client, or you need a secure, publicly available callback URL to interact with a web service. You could go ahead and upload your app to a hosting platform like Heroku, but then every time you make an update, you’d have to push those changes to your host server…not great.&lt;/p&gt;

&lt;p&gt;Luckily, there’s ngrok. Ngrok is a handy tool that creates a secure, publicly accessible tunnel URL to an application that’s running on localhost. You can share the tunnel URL so others can view your work, or you can create publicly accessible routes to do things like complete an Oauth handshake.&lt;/p&gt;

&lt;p&gt;In this tutorial, we’ll build a super simple Node app for BigCommerce and demonstrate how you can use ngrok to retrieve an Oauth token from the BigCommerce auth service and install the app in your store, all while still working locally. Consider this your comprehensive guide to testing, running, and authenticating BigCommerce apps locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is ngrok?
&lt;/h2&gt;

&lt;p&gt;Ngrok is a free program that exposes a process running on your localhost to the public internet. When you start up ngrok, you specify which port your local server is running on and ngrok creates a secure tunnel URL to make the local application publicly accessible. Visit the ngrok URL and you’ll see the same thing you see when visiting &lt;a href="http://localhost:myport"&gt;http://localhost:myport&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When you start ngrok, you’ll see a printout like this in your terminal:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/800/0*6yc5G5EsUwJ6eJFM" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/800/0*6yc5G5EsUwJ6eJFM" alt="ngrok dashboard" title="ngrok dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice those two forwarding addresses? Ngrok provides both an https and an http version of the URL that points to localhost. Ngrok also provides a Web Interface dashboard that prints out details on any http traffic that’s going through your tunnel. This can be extremely useful during app development, especially when dealing with webhooks.&lt;/p&gt;

&lt;p&gt;By default, ngrok generates a random subdomain every time you start it up. That’s fine for testing, but it can be a pain if you’re working on a project over a span of time and have to keep updating the URLs in your project every time you restart ngrok. If you sign up for a paid plan, ngrok allows you to designate a custom subdomain, so you’ll have the same URL every time.&lt;/p&gt;

&lt;p&gt;Really, the best way to explain how ngrok works is to show you. Let’s download ngrok and spin up a quick app to run on localhost to demonstrate.&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Set Up ngrok
&lt;/h2&gt;

&lt;p&gt;Ready to get started? You can install ngrok using npm (my preferred method) or you can install manually.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install with npm
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Be sure you have &lt;a href="https://nodejs.org/en/download/"&gt;Node.js&lt;/a&gt; installed on your computer. Run the following terminal command to confirm Node is installed and check your version:&lt;br&gt;
&lt;code&gt;node -v&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run &lt;code&gt;npm install -g ngrok&lt;/code&gt; to install ngrok globally. You can now run ngrok commands from any directory.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Install manually
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Head to &lt;a href="https://ngrok.com/download"&gt;https://ngrok.com/download&lt;/a&gt; and download the package that corresponds to your operating system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unzip the file somewhere easy to access, like the root folder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can either navigate to the folder where you unzipped ngrok to run it, or if you want to run ngrok from any location, you can move it to a directory which is in your $PATH, usually /usr/local/bin.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Start ngrok
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open a terminal window and navigate to the location where you unzipped ngrok. If you’ve installed ngrok globally or moved it to your $PATH, you can go ahead and run ngrok from any directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the following command to start ngrok and create a tunnel to localhost port 3000:&lt;br&gt;
&lt;code&gt;ngrok http 3000&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Press Ctrl + C to stop ngrok.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Create an Express App
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://expressjs.com/"&gt;Express&lt;/a&gt; is a framework for creating skeleton Node.js apps. It’s a great way to quickly create the file structure for your app.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install the express generator command line tool with the following terminal command:&lt;br&gt;
&lt;code&gt;npm install express-generator -g&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create the app. We’re specifying that the app should use the handlebars view engine and be created in a folder called myapp: &lt;br&gt;
&lt;code&gt;express — view=hbs myapp&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navigate into the myapp folder:&lt;br&gt;
&lt;code&gt;cd myapp&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the dependencies:&lt;br&gt;
&lt;code&gt;npm install&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start the app with the following command:&lt;br&gt;
&lt;code&gt;npm start&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Tunnel ngrok to localhost
&lt;/h2&gt;

&lt;p&gt;Time to put the pieces together. We’ve installed ngrok and created a skeleton app using Express. Now, we’ll start the application and ngrok to see the tunnel URL in action.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open a terminal window and navigate to your myapp directory. Run &lt;code&gt;npm start&lt;/code&gt; to start the app. By default, Express generator apps start the server on localhost:3000. If you want to change the port, it’s defined in the app’s bin/www file on line 15, but we’ll leave it on port 3000 for now.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open a browser window and navigate to &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;. You should see the Express app home page:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/800/0*CPknxeD9UykxzsPx" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/800/0*CPknxeD9UykxzsPx" alt="express localhost" title="express localhost"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open a new terminal window (leave the first terminal window running) and start ngrok on port 3000:&lt;br&gt;
ngrok http 3000&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy the https forwarding URL from the terminal and paste it into a new browser tab. You should see the same Express app homepage that you saw on your localhost URL:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/800/0*a1XYZL9mtajn5Y2l" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/800/0*a1XYZL9mtajn5Y2l" alt="express ngrok" title="express ngrok"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hooray! This may not look like much yet, but we’ve already demonstrated a powerful feature of ngrok. You could email your ngrok forwarding URL to a friend, and they’d see the same Express app homepage (as long as you’ve got ngrok running in your terminal). That’s pretty cool, but next we’ll show how you can use ngrok to do even more. We’ll create a forwarding URL that will allow us to create publicly accessible routes within the app so we can complete the Oauth flow necessary to install the app in a BigCommerce store.&lt;/p&gt;

&lt;h2&gt;
  
  
  BigCommerce App Authentication
&lt;/h2&gt;

&lt;p&gt;Before we move on, it helps to have a little background on BigCommerce app authentication, to illustrate why ngrok is needed to install an app that’s still hosted locally.&lt;/p&gt;

&lt;p&gt;BigCommerce apps use Oauth to programmatically generate an API token against a store during installation. Once an app has received an API token for a store, the app can save the token in a database for reuse when calling the API.&lt;/p&gt;

&lt;p&gt;The process to receive an Oauth token requires a little back and forth between BigCommerce and the app host. First, the app needs to request a temporary auth code from BigCommerce. When BigCommerce sends the temporary token, it sends along a couple of other pieces of information as well: the scopes that have been authorized for the API token and the hash, or identifier, for the store that’s installing the app.&lt;/p&gt;

&lt;p&gt;Next, the app posts back a response containing a series of claims that let the BigCommerce auth service know it’s okay to return a real Oauth token. Those claims include the temporary auth token received previously from BigCommerce, the store hash, the scopes, and a Client Id and Client Secret that were provided during app registration. If everything checks out, the BigCommerce auth service sends back a permanent Oauth token and the app shows ‘Installed’ in the store control panel.&lt;/p&gt;

&lt;p&gt;All of these network requests need to happen over publicly accessible URLs. When testing app installation and authentication, we either need to host the app on a server, or a platform like Heroku, or use a tool like ngrok to create tunnel URLs from localhost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Register the App
&lt;/h2&gt;

&lt;p&gt;To install an app in a BigCommerce store, you’ll need, not surprisingly….a store. Sign up for a free trial at &lt;a href="https://www.bigcommerce.com/"&gt;https://www.bigcommerce.com/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Then, sign up for a Dev Tools account at &lt;a href="https://developer.bigcommerce.com/"&gt;https://developer.bigcommerce.com/&lt;/a&gt; by clicking Create Account in the top right corner. Be sure to use the same email address that you used to sign up for your trial store. Using the same email address links your trial store and your Dev Tools accounts, so any apps that you create in Dev Tools will be available for installation in the Draft Apps area of your store’s control panel.&lt;/p&gt;

&lt;p&gt;Dev Tools is the workspace for creating BigCommerce apps. It’s where you go to register a new app and manage app listing details if you’re a vendor in the App Marketplace. For now, we’ll just do the minimum steps to register a new app and get a Client Id and Client Secret.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Log in to Dev Tools and click the orange &lt;strong&gt;Create an app&lt;/strong&gt; button.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter a name for your app. This could be anything — My Test App, Node App, whatever you’d like.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Create App&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the &lt;strong&gt;Edit App&lt;/strong&gt; icon on the app you created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On Step 1, you can skip filling out the profile form. This just collects information that BigCommerce needs for developers who want to submit their app to the App Marketplace. It’s not required, but I do like to go ahead and upload an image to the App summary area at the bottom. The image will show on the card for your draft app in the control panel. Again, not required, but it does look nicer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Skip Step 2: App Details and proceed to Step 3. App details are required only for developers who want to submit an app to the Marketplace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On Step 3, fill in the Callback URL fields, replacing example.com with your https forwarding URL from ngrok. For example:&lt;br&gt;
Auth: &lt;a href="https://4022ffe4.ngrok.io/auth"&gt;https://4022ffe4.ngrok.io/auth&lt;/a&gt;&lt;br&gt;
Load: &lt;a href="https://4022ffe4.ngrok.io/load"&gt;https://4022ffe4.ngrok.io/load&lt;/a&gt;&lt;br&gt;
Uninstall: &lt;a href="https://4022ffe4.ngrok.io/uninstall"&gt;https://4022ffe4.ngrok.io/uninstall&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Next&lt;/strong&gt; until you reach Step 6, then click &lt;strong&gt;Update and Close&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Create Routes in Express
&lt;/h2&gt;

&lt;p&gt;During app registration, we defined three callback URLs: Auth, Load, and Uninstall. These URLs tell BigCommerce: when someone installs, loads, or uninstalls my app, here’s where you should send the http request for that action. Next, we’ll create those routes in the Express app to handle the authorization, load, and uninstall requests from BigCommerce.&lt;/p&gt;

&lt;p&gt;A route listens for an http request, a GET or a POST, to a particular path and then does &lt;em&gt;something&lt;/em&gt;, like running a function or calling a response method, when the http request happens.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create the Auth route:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install the &lt;a href="https://github.com/getconversio/node-bigcommerce"&gt;BigCommerce Node Client&lt;/a&gt; by running npm install node-bigcommerce in your myapp directory. This package was written by the developers at &lt;a href="https://conversio.com/"&gt;Conversio&lt;/a&gt;, and is used to authenticate with and call the BigCommerce API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new file in the routes directory called auth.js.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Paste the following into the file contents:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express'),
router = express.Router(),
BigCommerce = require('node-bigcommerce');

const bigCommerce = new BigCommerce({
clientId: 'your Client Id from app registration',
secret: 'your Client Secret from app registration',
callback: 'https://your-ngrokURL/auth',
responseType: 'json'
});

router.get('/', (req, res, next) =&amp;gt; {
bigCommerce.authorize(req.query)
.then(data =&amp;gt; console.log(data))
.then(data =&amp;gt; res.render('auth', { title: 'Authorized!' })
.catch(err));
});
module.exports = router;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here, we’re requiring the Express router and BigCommerce Node Client at the top of the file and instantiating a new BigCommerce config object.&lt;/p&gt;

&lt;p&gt;Take a look at the function below the BigCommerce config object. With &lt;code&gt;router.get(‘/’, (req, res, next)&lt;/code&gt;, we’re telling the router, when you receive a GET request to this path (this path is /auth, because we’re in the routes/auth.js file), call the authorize function from the Node Client dependency.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/getconversio/node-bigcommerce/blob/master/lib/bigcommerce.js#L75"&gt;authorize function&lt;/a&gt; returns a data object from BigCommerce containing the store hash, the user’s email address (to identify the user), and the Oauth token associated with the store. If we were to develop this app further, we’d want to save that information to a database for reuse.&lt;/p&gt;

&lt;p&gt;Once we return the Oauth token, we call res.render to render a view called ‘auth’ that passes in the text “Authorized!”&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Replace the values for your Client Id, your Client Secret, and your ngrok tunnel URL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create the ‘auth’ view by creating a new file in your Views folder called auth.hbs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Paste the following into the file contents: &lt;br&gt;
&lt;code&gt;&amp;lt;h1&amp;gt;{{title}}&amp;lt;/h1&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Create the Load route:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a new file in your Routes folder called load.js&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Paste the following into the file contents:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express'),
router = express.Router(),
BigCommerce = require('node-bigcommerce');
const bigCommerce = new BigCommerce({
secret: 'your Client Secret',
responseType: 'json'
});

router.get('/', (req, res, next) =&amp;gt; {
try {
const data = bigCommerce.verify(req.query['signed_payload']);
console.log(data);
res.render('welcome', { title: 'Welcome!'});
} catch (err) {
next(err);
}
});

module.exports = router;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Replace the value for ‘secret’ with your Client Secret. Similar to the /auth route we created, we’re specifying a callback function to execute after a GET request to the /load route. We’re calling the &lt;a href="https://github.com/getconversio/node-bigcommerce/blob/master/lib/bigcommerce.js#L38"&gt;verify&lt;/a&gt; function which validates that the request came from BigCommerce and identifies the store and user. When that’s successful, we console log the data object and render the view called ‘welcome.’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create the ‘welcome’ view by creating a new file in your Views directory called welcome.hbs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Paste the following into the file contents: &lt;br&gt;
&lt;code&gt;&amp;lt;h1&amp;gt;{{title}}&amp;lt;/h1&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Create the Uninstall Route:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a new file in your Routes directory called uninstall.js&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Paste the following into the file contents:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express'),
router = express.Router(),
BigCommerce = require('node-bigcommerce');
const bigCommerce = new BigCommerce({
secret: 'Your Client Secret',
responseType: 'json'
});

router.get('/', (req, next) =&amp;gt; {
try {
const data = bigCommerce.verify(req.query['signed_payload']);
console.log(data);
} catch (err) {
next(err);
}
});

module.exports = router;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Replace the value for ‘secret’ with your Client Secret. In the /uninstall callback, we’re using the verify function to decode the signed payload sent from BigCommerce and logging the payload identifying the user who uninstalled the app. We’re not rendering a view in this case, because any HTML sent back to BigCommerce wouldn’t be rendered by BigCommerce.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Load Router Modules in App.js
&lt;/h2&gt;

&lt;p&gt;Before we can use the route modules we’ve created, we need to mount the router modules on a path in the main app file.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the following near the top of your app.js file:&lt;/li&gt;
&lt;/ol&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var auth = require(‘./routes/auth’);
var load = require(‘./routes/load’);
var uninstall = require(‘./routes/uninstall’);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Locate these lines, near the middle of the app.js file:&lt;/li&gt;
&lt;/ol&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.use(‘/’, index);
app.use(‘/users’, users);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Beneath them, add:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.use(‘/auth’, auth);
app.use(‘/load’, load);
app.use(‘/uninstall’, uninstall);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Install the App
&lt;/h2&gt;

&lt;p&gt;Now that we have the app wired up to the appropriate route paths, it’s time to install the app in your store.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Start the Express app by running the &lt;code&gt;npm start&lt;/code&gt; command in your myapp directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open a second terminal window and start ngrok on port 3000: &lt;br&gt;
&lt;code&gt;ngrok http 3000&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Be sure to update the ngrok URL in Dev Tools to match the ngrok URL in your current session.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Log in to your BigCommerce store and navigate to Apps&amp;gt;My Apps&amp;gt;My Draft Apps tab.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Learn More&lt;/strong&gt; on your app card and then click &lt;strong&gt;Install&lt;/strong&gt;. You should see your app’s Authorized! Message. The Authorized! view indicates that we’ve successfully received an Oauth token from BigCommerce.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test the Load route by returning to the My Apps section in the control panel. Now that the app is installed, you’ll see two new buttons: Load and Uninstall. Click the &lt;strong&gt;Load&lt;/strong&gt; button to render the Welcome view.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now, click the &lt;strong&gt;Uninstall&lt;/strong&gt; button. The app will be removed from the My Apps section. Check your terminal for the auth, load, and uninstall data objects that were logged to the console.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;I’ve installed ngrok. Why am I getting ‘command not found’ when I try to start it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You’re likely not running ngrok from the working directory for the executable file. You can either move the file to your $PATH directory, or navigate to the directory containing the ngrok .exe file. For example, if you unzipped ngrok in your root directory, you can run it using:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd ~&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./ngrok http 3000&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How can I use ngrok to test webhooks?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Webhooks allow you to listen for events that happen on a third party’s platform. For example, your app might want to receive a notification when a BigCommerce product’s inventory changes so your app can take an action of some kind.&lt;/p&gt;

&lt;p&gt;When you register a webhook, you can provide an ngrok tunnel URL as the destination URL. When the webhook event happens, you’ll receive the webhook data object through your tunnel. You can display the details of the data object in your ngrok Web Interface dashboard and handle the event within your app.&lt;/p&gt;

&lt;p&gt;For more details on testing webhooks with ngrok, see this tutorial on &lt;a href="https://developer.bigcommerce.com/api-docs/getting-started/webhooks/setting-up-webhooks"&gt;registering and testing webhooks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why do I get a 502 bad gateway error when I visit my ngrok tunnel URL?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ngrok expects a web server to be running on localhost. If there isn’t a server running, you’ll see a 502 error accompanied by a message that ngrok failed to complete the tunnel connection. By default, Express generator apps start a server on port 3000, so you’ll just want to make sure you start your app before making requests to your ngrok URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we installed ngrok and used it to tunnel the routes that we registered on our locally hosted app to publicly accessible callback URLs. Great job! You’re now well on your way to building and testing your apps locally — no need to deploy your changes to an app host while you’re still in the development phase.&lt;/p&gt;

&lt;p&gt;Use this as a starting point to build out more complexity in your app: save your Oauth token to a database and use it to call the BigCommerce API or create view templates that provide a UI for your app users. Looking for Hello World apps in Python, PHP, or Ruby? Visit the BigCommerce &lt;a href="https://developer.bigcommerce.com/tools-resources"&gt;Tools &amp;amp; Resources&lt;/a&gt; page for sample apps and API clients in other languages.&lt;/p&gt;

&lt;p&gt;Let us know what you’re working on, ask us questions, send us your feedback! Comment below or tweet us &lt;a href="https://twitter.com/BigCommerceDevs"&gt;@BigCommerceDevs&lt;/a&gt;&lt;/p&gt;


</description>
      <category>bigcommerce</category>
      <category>ngrok</category>
      <category>node</category>
      <category>apps</category>
    </item>
  </channel>
</rss>
