<?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: William Bishop</title>
    <description>The latest articles on Forem by William Bishop (@bishopwm).</description>
    <link>https://forem.com/bishopwm</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%2F937048%2F38aace6f-4c03-492e-8a2a-fc167bd930a2.jpg</url>
      <title>Forem: William Bishop</title>
      <link>https://forem.com/bishopwm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bishopwm"/>
    <language>en</language>
    <item>
      <title>Bring visual collaboration to life with Postman and Miro APIs</title>
      <dc:creator>William Bishop</dc:creator>
      <pubDate>Wed, 30 Aug 2023 10:40:52 +0000</pubDate>
      <link>https://forem.com/mirodevelopers/bring-visual-collaboration-to-life-with-postman-and-miro-apis-435c</link>
      <guid>https://forem.com/mirodevelopers/bring-visual-collaboration-to-life-with-postman-and-miro-apis-435c</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally published on the &lt;a href="//https%3A%2F%2Fblog.postman.com%2Fbring-visual-collaboration-to-life-with-postman-and-miro-apis%2F"&gt;Postman blog&lt;/a&gt; on August 18th, 2023.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With the power of Postman, the options for dynamically creating content with third-party platforms and tools are seemingly endless. This was the inspiration for a recent &lt;a href="https://www.youtube.com/watch?v=gu9-kwi8Dns"&gt;Postman livestream&lt;/a&gt; exploring how we can leverage the &lt;a href="https://developers.miro.com/"&gt;Miro Developer Platform's&lt;/a&gt; REST APIs to create content on a Miro board - all from within Postman.&lt;/p&gt;

&lt;p&gt;Before diving into the details of how you can streamline your workflow with Postman and unlock new possibilities in Miro, let's start with a quick primer: what is visual collaboration in Miro? Well, simply put, it's a collection of connected activities that allow you to communicate and collaborate across formats, tools, channels, and time zones - without the constraints of physical location, meeting space, and whiteboards.&lt;/p&gt;

&lt;p&gt;The Miro Developer Platform allows you to extend the power of visual collaboration and interact with Miro boards via its &lt;a href="https://developers.miro.com/reference/api-reference"&gt;robust suite of REST APIs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JZNjnMni--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vifrst8g8q2ojhe1an6p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JZNjnMni--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vifrst8g8q2ojhe1an6p.png" alt="Miro board with sticky notes and planning workflows" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;In order to use the Miro REST API with Postman, you’ll need to first make sure you have a Miro account and some developer credentials to generate an access_token. You can find all the necessary details to get started &lt;a href="https://developers.miro.com/docs/rest-api-build-your-first-hello-world-app"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Miro Postman Collection
&lt;/h3&gt;

&lt;p&gt;To make things even easier, you can leverage the &lt;a href="https://www.postman.com/miro-developer-platform/workspace/miro-developer-platform/collection/20467754-1a7d3514-f19f-4a86-9001-d694f160da3d"&gt;Miro Developer Platform public collection&lt;/a&gt; in Postman, which includes an authorization helper to make getting an access token a breeze. By simply entering any Miro endpoint into Postman, you’ll see an option to set up a new authorization method, providing a frictionless experience for accessing Miro’s APIs (more details on this awesome new helper &lt;a href="https://blog.postman.com/easier-api-authentication-in-postman/"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hwxv0r-7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/68x79p62xse52oh8jd5f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hwxv0r-7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/68x79p62xse52oh8jd5f.png" alt="Authorization helper in Postman" width="800" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating sticky notes dynamically from Postman
&lt;/h2&gt;

&lt;p&gt;Once you’ve authorized and have your access_token saved to your Postman environment, you’re ready to make a request to the Miro API.&lt;/p&gt;

&lt;p&gt;But rather than just make a single request that, for instance, creates a sticky note on a Miro board, let’s take advantage of &lt;a href="https://learning.postman.com/docs/sending-requests/variables/"&gt;Postman variables&lt;/a&gt; and the &lt;a href="https://learning.postman.com/docs/collections/running-collections/intro-to-collection-runs/"&gt;Postman Collection Runner&lt;/a&gt; feature to automate a number of requests, using some content from outside of Postman.&lt;/p&gt;

&lt;p&gt;To do this, we can navigate to the Sticky Notes folder in the Miro Developer Platform collection, and leverage the &lt;a href="https://developers.miro.com/reference/create-sticky-note-item"&gt;Create Sticky Note Item&lt;/a&gt; endpoint. Navigate to the &lt;strong&gt;Body&lt;/strong&gt; tab in Postman, and you’ll see some JSON already populated for the body of the request. For the content field in the request body, we can create a new environment variable—&lt;code&gt;{{content}}&lt;/code&gt;. We can do the same for the x, y fields in the position object—&lt;code&gt;{{x}}&lt;/code&gt; and &lt;code&gt;{{y}}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, in the request URL, we will need to pass the ID of a Miro board under the team we authorized when we set up our authorization initially. If there aren’t any boards, simply create a new one from the Miro dashboard.&lt;/p&gt;

&lt;p&gt;Hit &lt;strong&gt;Save&lt;/strong&gt; and let’s populate these variables from some content outside of Postman.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K_l8HRuY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1mqbv9l1vd1ojmf3aw2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K_l8HRuY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1mqbv9l1vd1ojmf3aw2q.png" alt="Miro REST API request in Postman" width="800" height="647"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate sticky notes from CSV file
&lt;/h2&gt;

&lt;p&gt;To start, we’ll need a .csv file that we can work with. Let’s create a basic .csv file where the first line is our header, and the following lines are the content and coordinates that we will feed into our requests in Postman to create sticky notes via the Miro API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--12JpN7vA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/53fphn3tujsi90f2drdk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--12JpN7vA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/53fphn3tujsi90f2drdk.png" alt="CSV content for import from file to Postman variables" width="790" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once we’ve got our .csv file set up, we can use the Postman Collection Runner to select the request we’ve already set up for the &lt;a href="https://developers.miro.com/reference/create-sticky-note-item"&gt;Create sticky note item&lt;/a&gt; endpoint and choose a number of iterations. We’ll do just a few iterations, and select the .csv file we created for the Data File Type. Hit &lt;strong&gt;Run Miro Developer Platform&lt;/strong&gt; and go to the Miro board you specified in the &lt;em&gt;Create sticky note item&lt;/em&gt; request earlier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X7ammi4P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/388w7pielase1gxg96ph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X7ammi4P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/388w7pielase1gxg96ph.png" alt="Sticky notes generated via CSV in Miro" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Voila!&lt;/em&gt; We can see our new stickies being generated from our .csv file as the Postman Collection Runner initiates.&lt;/p&gt;

&lt;p&gt;While this is a simple example, you can imagine how many possibilities there are to combine the power of Postman and Miro to generate and manipulate content on a Miro board! But don't just take my word for it - you can take it even further.&lt;/p&gt;

&lt;h2&gt;
  
  
  Expand your workflow with Postman Flows and Miro
&lt;/h2&gt;

&lt;p&gt;Interested in exploring further automation? Check out how we leveraged &lt;a href="https://learning.postman.com/docs/postman-flows/gs/flows-overview/"&gt;Postman Flows&lt;/a&gt; to add some more complexity to our variables and inputs in an effort to create even more dynamic workflows between Postman and Miro.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/gu9-kwi8Dns"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  That's a wrap!
&lt;/h2&gt;

&lt;p&gt;In addition to the capabilities we demonstrated here, there's so much more you can do with Postman and the &lt;a href="https://developers.miro.com/"&gt;Miro Developer Platform&lt;/a&gt;. Want to keep going? You can also build applications with Miro's &lt;a href="https://developers.miro.com/docs/miro-web-sdk-introduction"&gt;Web SDK&lt;/a&gt; for a frontend experience directly on a Miro board, and use Miro's &lt;a href="https://developers.miro.com/reference/api-reference"&gt;REST API&lt;/a&gt; for authorization and further automation.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article was originally published on the &lt;a href="https://blog.postman.com/bring-visual-collaboration-to-life-with-postman-and-miro-apis/"&gt;Postman blog&lt;/a&gt; on August 18th, 2023.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>postman</category>
      <category>restapi</category>
      <category>miro</category>
      <category>integration</category>
    </item>
    <item>
      <title>My First Server and REST API: Essentials for Frontenders</title>
      <dc:creator>William Bishop</dc:creator>
      <pubDate>Thu, 12 Jan 2023 12:13:17 +0000</pubDate>
      <link>https://forem.com/bishopwm/my-first-server-and-rest-api-essentials-for-frontenders-2gnk</link>
      <guid>https://forem.com/bishopwm/my-first-server-and-rest-api-essentials-for-frontenders-2gnk</guid>
      <description>&lt;p&gt;&lt;em&gt;Explore the essentials of integrating with 3rd party services, and take your web apps to the next level by getting familiar with the infrastructure necessary to call a REST API from a simple backend, using NodeJS + Express.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pnnem2x0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ravmzz2z1sqmvce6nae.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pnnem2x0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ravmzz2z1sqmvce6nae.jpg" alt="Image description" width="880" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;REST APIs aren’t just for backend developers or full stack gurus. In fact, incorporating 3rd party APIs into your frontend applications is a great way to expand the capabilities of your app and bring the power of an almost exponential number of external services to your offering. &lt;/p&gt;

&lt;p&gt;But in order to get the most out of REST APIs, you’ll need to understand the basics about how to efficiently call them, and what kind of infrastructure you’ll need to make requests from an app of your own. Luckily, it’s not too complicated and we’ve boiled it down to the essentials for you!&lt;/p&gt;

&lt;p&gt;Let’s get started! &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understand REST APIs’ role in frontend development&lt;/li&gt;
&lt;li&gt;Set up a backend / server&lt;/li&gt;
&lt;li&gt;Master an end to end example in NodeJS&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Even frontenders could benefit from a backend sometimes!
&lt;/h2&gt;

&lt;p&gt;So, what exactly is the value in leveraging REST APIs in frontend development, and why should we bother with a backend? Well, REST APIs are extremely versatile and open up tons of use cases.&lt;/p&gt;

&lt;p&gt;REST APIs can serve as a connection within complex software, or they can stand alone as their own product even. There are many successful companies who have taken an &lt;a href="https://swagger.io/resources/articles/adopting-an-api-first-approach/"&gt;API-first&lt;/a&gt; approach, where their open APIs are the primary value driver behind their business model. Some successful examples of this can be seen in companies we've all likely heard of, such as eBay, Twilio, Stripe, and more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---14a11oL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jdt6em96lcb31cf9j77r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---14a11oL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jdt6em96lcb31cf9j77r.png" alt="Image description" width="880" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ebay’s former head of developer ecosystem, &lt;a href="https://mobile.twitter.com/latestfromtv"&gt;Tanya Vlahovic&lt;/a&gt;, put it really well:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"...we allow...developer[s] to take all of these building blocks and uniquely combine them [to form]...great quality experiences."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s just another reminder that being an Engineer with the ability to confidently leverage REST APIs can open many doors for you. &lt;/p&gt;

&lt;p&gt;Alright, but how do we get started? Well, first we’ll need to set up a simple backend and server. &lt;/p&gt;

&lt;h2&gt;
  
  
  Create a NodeJS project with an Express server
&lt;/h2&gt;

&lt;p&gt;Especially in frontend development, setting up the infrastructure necessary to make API requests (and set up a server) can be a bit intimidating. Maybe it has even prevented you from taking advantage of these capabilities—until now. 😉&lt;/p&gt;

&lt;p&gt;While of course there are exceptions to needing a backend and server, such as serverless functions in frameworks like NextJS, we will stick to the basics for now. We’ve boiled down the essentials for getting a NodeJS script up and running, in order to call a REST API in &lt;strong&gt;four easy steps in NodeJS&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set up a NodeJS project&lt;/li&gt;
&lt;li&gt;Install Express&lt;/li&gt;
&lt;li&gt;Create an &lt;code&gt;index.js&lt;/code&gt; file and import Express&lt;/li&gt;
&lt;li&gt;Instantiate Express and send a test request&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s start from step 1.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Set up a NodeJS project
&lt;/h2&gt;

&lt;p&gt;We’ll run through an example in NodeJS. If you aren’t familiar with Node and npm, you can find more details on this &lt;a href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To set up a new NodeJS project, we’ll need to first create a new directory to house a package.json file. Within this new directory, we can then run the following command in our terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate a package.json file for us, which is essentially a simple manifest of sorts for our NodeJS script, which by default will take place in index.js. (You can use another filename if you like, just be sure to update your package.json!)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VMfN4JFK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zfwuxrwxt10rjwqsis6h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VMfN4JFK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zfwuxrwxt10rjwqsis6h.png" alt="Image description" width="880" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Install Express
&lt;/h2&gt;

&lt;p&gt;Now that we have our Node project created, we will run the following command within our project directory, which will generate a node_modules folder and a package-lock.json file — two essential components for housing resources and versioning our Node app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Create an index.js file and import Express
&lt;/h2&gt;

&lt;p&gt;Next, we can create our main script, index.js, and import our Express server instance.&lt;/p&gt;

&lt;p&gt;First, create an index.js file within the same main directory. At the top of this file, we can import Express using the following statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require(“express”);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Instantiate Express server and send request
&lt;/h2&gt;

&lt;p&gt;And lastly, we can now instantiate our Express server and send a test request to a simple GET endpoint in our app.&lt;/p&gt;

&lt;p&gt;First, we instantiate Express using this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const app =  express();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we create a GET endpoint, from which we’ll send a simple response to the browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.get(‘/’, (req, res) =&amp;gt; {
    res.send(‘hello world’);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And lastly, we need to specify a port for our server to listen on—let’s use 3000:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.listen(3000, () =&amp;gt; console.log(`Listening on port ${port}!`))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now we can run our script…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;…and navigate to localhost:3000 in our browser. On success, our terminal should show the console log that our app is listening. And if we go to our browser at localhost:3000, we should see the "hello world" text that we included in our endpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SF5ToU-k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2fwliaf3amy85szbnvk3.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SF5ToU-k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2fwliaf3amy85szbnvk3.jpeg" alt="Image description" width="880" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, this is a simplified walkthrough of how to set up a server in NodeJS, using express, so you may need to add or tweak a few lines of your own — but these are the main steps necessary.&lt;/p&gt;

&lt;p&gt;But just setting up a server by itself isn't super useful, right? &lt;/p&gt;

&lt;p&gt;So, instead of simply sending some "hello world" text to the browser within our app.get() function, we could instead make a request to a REST API within this function, and utilize the response in another part of our app. Or, we could send the response from such a request to our browser, similar to our hello world text in the above example.&lt;/p&gt;

&lt;p&gt;Let’s move on to an example script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making an API request from a NodeJS script
&lt;/h2&gt;

&lt;p&gt;At Miro, we have several sample scripts that demo this flow. Let’s take a closer look at an end to end example of calling a REST API from NodeJS with our &lt;code&gt;node-oauth&lt;/code&gt; repo, which you can clone here:&lt;br&gt;
&lt;strong&gt;&lt;a href="https://github.com/miroapp/app-examples/tree/main/examples/node-oauth"&gt;Miro node-oauth repository&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, we’ll follow similar steps as before in setting up our index.js file, and we will additionally use two other packages—&lt;a href="https://www.npmjs.com/package/dotenv"&gt;dotenv&lt;/a&gt; for working with sensitive variables, and &lt;a href="https://www.npmjs.com/package/axios"&gt;axios&lt;/a&gt; for making http requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Require sensitive environment variables (Client ID, Client Secret, Miro Board ID)
require("dotenv/config");

// Require Axios for handling HTTP requests to Miro /oauth and Miro API endpoints
const axios = require("axios");

// Require ExpressJS for local server
const express = require("express");
const app = express();

// Call Express server
app.get("/", (req, res) =&amp;gt; {...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within our app.get() endpoint, we will call the Miro REST API, but first let’s continue setting up the rest of our script by making sure our server is listening at a specified port. We’ll put this at the end of our script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.listen(3000, () =&amp;gt; console.log(`Listening on localhost, port 3000`));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, back to the &lt;code&gt;app.get()&lt;/code&gt; function. Within here, we’ll do two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retrieve an &lt;code&gt;access_token&lt;/code&gt; for the Miro REST API, by calling &lt;a href="https://developers.miro.com/docs/getting-started-with-oauth"&gt;Miro’s OAuth2.0 endpoint&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Call a &lt;a href="https://developers.miro.com/reference/get-boards"&gt;Miro REST API endpoint&lt;/a&gt; to retrieve a Miro Board using our &lt;code&gt;access_token&lt;/code&gt;, and send the response to the browser&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In &lt;a href="https://github.com/miroapp/app-examples/blob/main/examples/node-oauth/index.js#L36"&gt;line 36 of index.js&lt;/a&gt;, we’re calling the OAuth endpoint.&lt;/p&gt;

&lt;p&gt;And in &lt;a href="https://github.com/miroapp/app-examples/blob/main/examples/node-oauth/index.js#L63"&gt;line 63 of index.js&lt;/a&gt;, we’re calling Miro’s GET Board endpoint, using the &lt;code&gt;access_token&lt;/code&gt; we retrieved in line 36.&lt;/p&gt;

&lt;p&gt;And finally, we’re sending the response to our browser, in &lt;a href="https://github.com/miroapp/app-examples/blob/main/examples/node-oauth/index.js#L68"&gt;line 68 of index.js&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Master REST APIs with Miro
&lt;/h2&gt;

&lt;p&gt;Want to walk through this script in a bit more detail and see the output in the browser? Check out our on-demand educational training series, REST API Essentials for Frontenders, linked above!&lt;/p&gt;

&lt;p&gt;And keep going with REST APIs, leveraging the &lt;a href="https://developers.miro.com/"&gt;Miro Developer Platform’s&lt;/a&gt; assortment of &lt;a href="https://github.com/miroapp/app-examples#rest-apis"&gt;sample apps&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;You can even &lt;a href="https://miro.com/app/dashboard/?createDevTeam=1"&gt;create a developer team&lt;/a&gt; and start quickly calling Miro’s REST APIs directly from our documentation. You can find the full &lt;a href="https://developers.miro.com/docs/rest-api-build-your-first-hello-world-app"&gt;Getting Started flow here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let us know what you build! We’re always happy to talk shop with fellow developers. 🙂&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Did you like learning more about REST APIs and how to leverage the Miro Developer Platform? For more inspiration or questions, follow along with our &lt;a href="https://community.miro.com/developer-platform-and-apis-57"&gt;Developer Community&lt;/a&gt; on &lt;a href="https://www.youtube.com/channel/UC37GT5mtEbYmnxXlKTIJ-rw"&gt;YouTube&lt;/a&gt;, &lt;a href="https://github.com/miroapp/app-examples"&gt;GitHub&lt;/a&gt;, and &lt;a href="https://discord.gg/9FUpabwXQK"&gt;Discord&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>restapi</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Taking the fear out of authorization: OAuth essentials for frontenders</title>
      <dc:creator>William Bishop</dc:creator>
      <pubDate>Mon, 12 Dec 2022 12:50:01 +0000</pubDate>
      <link>https://forem.com/bishopwm/taking-the-fear-out-of-authorization-oauth-essentials-for-frontenders-7lk</link>
      <guid>https://forem.com/bishopwm/taking-the-fear-out-of-authorization-oauth-essentials-for-frontenders-7lk</guid>
      <description>&lt;p&gt;&lt;em&gt;Explore the essentials of OAuth2.0, and how to take your web applications to the next level by removing the complexities around integrating 3rd party REST APIs in frontend development.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://medium.com/r/?url=https%3A%2F%2Foauth.net%2F" rel="noopener noreferrer"&gt;OAuth2.0&lt;/a&gt; is one of the most commonly dreaded authorization methods to implement in frontend development - and understandably so! With its various flows, exchanges, and other intricacies, it can be overwhelming. But, it's also an essential authorization flow that opens the door to a seemingly unlimited number of 3rd party use cases.&lt;/p&gt;

&lt;p&gt;Let's take the fear out of OAuth2.0!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understand OAuth's role in frontend development&lt;/li&gt;
&lt;li&gt;Explore common flows, or grant types&lt;/li&gt;
&lt;li&gt;Master the authorization code flow&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  OAuth2.0 isn't just for backenders
&lt;/h2&gt;

&lt;p&gt;If you're a frontend developer, you've most likely encountered OAuth2.0 in some capacity, but perhaps you've never needed to fully implement it in your own applications, or it was handled separately in backend development.&lt;/p&gt;

&lt;p&gt;But actually, &lt;a href="//https%3A%2F%2Foauth.net%2F2%2F"&gt;OAuth2.0 is an essential authorization flow&lt;/a&gt; for all types of developers. And by equipping yourself with the context and confidence necessary to implement it all on your own, you open up the door to new capabilities to complement the native ones you've already built. Not to mention, there might come a time, even in frontend development, when you're tasked to incorporate some of your end users' favorite tools like Miro, Google, Zoom, and more.&lt;/p&gt;

&lt;p&gt;So, let's remove some of the complexities that can cause us to avoid OAuth2.0 in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  OAuth2.0 flows in a nutshell
&lt;/h2&gt;

&lt;p&gt;OAuth2.0 supports various different "flows", or &lt;a href="//https%3A%2F%2Foauth.net%2F2%2Fgrant-types%2F"&gt;grant types&lt;/a&gt;, as you'll see them officially referenced. These are essentially just different ways of getting to the same end-goal: receiving authorization to work with some type of resource (via an API).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft54hyc7a7cd108vgbtmz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft54hyc7a7cd108vgbtmz.png" alt="Image description" width="800" height="492"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Source: OAuth.io&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;However, there are many different flows, and they apply to a variety of different use cases or implementations. You can find the full list and explanation of each flow on &lt;a href="https://oauth.net/2/grant-types/" rel="noopener noreferrer"&gt;OAuth.net&lt;/a&gt;, but let’s cover a couple of the more common ones now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authorization Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://oauth.net/2/grant-types/authorization-code/" rel="noopener noreferrer"&gt;authorization code flow&lt;/a&gt; is one of the most common flows, especially in frontend development, where it’s expected that an end-user will provide their authorization in some sort of frontend UI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PKCE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://oauth.net/2/pkce/" rel="noopener noreferrer"&gt;PKCE&lt;/a&gt; is an extension for the authorization code flow, originally intended for mobile development. However, it was found to be an effective mechanism for all mediums, and is used to prevent CSRF and authorization code injection attacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implicit Grant&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You may see this referenced, but it’s a &lt;a href="https://oauth.net/2/grant-types/implicit/" rel="noopener noreferrer"&gt;legacy flow&lt;/a&gt;, and no longer a best practice/recommended grant type to leverage. It was found to be vulnerable to bad actors/risks upon returning an access token directly in an HTTP redirect (without any kind of exchange like in the &lt;em&gt;authorization code&lt;/em&gt; flow).&lt;/p&gt;
&lt;h2&gt;
  
  
  Mastering the authorization code flow
&lt;/h2&gt;

&lt;p&gt;Despite being one of the most popular implementations of OAuth2.0, the authorization code flow can seem daunting at first, given the number of steps. But once it’s broken down a bit, things become much simpler. There are &lt;strong&gt;5 main steps&lt;/strong&gt; in this flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;End user authorization&lt;/li&gt;
&lt;li&gt;Exchange of the authorization code&lt;/li&gt;
&lt;li&gt;Retrieval of an access token&lt;/li&gt;
&lt;li&gt;Request to the resource server&lt;/li&gt;
&lt;li&gt;Refresh of the access token&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s lay things out in layman’s terms and use some sample code snippets from a &lt;a href="https://github.com/miroapp/miro-rsc-workshop" rel="noopener noreferrer"&gt;sample app we’ve built in NextJS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, a user of your application will need to provide their consent, or authorize your application to access data on their behalf. This is step 1, and occurs when the end user is directed to the authorization URL that your app constructs, based on the resource owner (e.g., Miro, Google, etc.).&lt;/p&gt;

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

&lt;p&gt;Here’s an &lt;a href="https://github.com/miroapp/miro-rsc-workshop/blob/main/pages/api/signin.js" rel="noopener noreferrer"&gt;example function&lt;/a&gt;, where the two environment variables included are: a Miro-provided Client ID, and a specified callback URL, respectively:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function handler(req, res) {
 res.redirect(
 "https://miro.com/oauth/authorize?response_type=code&amp;amp;client_id=" +
 process.env.clientID +
 "&amp;amp;redirect_uri=" +
 process.env.redirectURL
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(You can find a more detailed explanation of constructing this URL in &lt;a href="https://developers.miro.com/docs/getting-started-with-oauth#prompt-users-to-install-your-app-in-miro" rel="noopener noreferrer"&gt;Miro’s OAuth2.0 starter guide&lt;/a&gt; as well.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Next, your application will need to receive a code parameter from the redirect url, immediately following the end user’s consent, and exchange this for an access_token — this all happens on your app’s backend/server. &lt;a href="https://github.com/miroapp/miro-rsc-workshop/blob/main/pages/api/redirect.js" rel="noopener noreferrer"&gt;This is steps 2 and 3&lt;/a&gt;, respectively:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import axios from "axios";

export default function handler(req, res) {
  let access_token;
  let refresh_token;

  if (req.query.code) {
    let url = `https://api.miro.com/v1/oauth/token?grant_type=authorization_code&amp;amp;client_id=${process.env.clientID}&amp;amp;client_secret=${process.env.clientSecret}&amp;amp;code=${req.query.code}&amp;amp;redirect_uri=${process.env.redirectURL}`;

    async function grabToken() {
      try {
        let oauthResponse = await axios.post(url);

        access_token = oauthResponse.data.access_token;
        refresh_token = oauthResponse.data.refresh_token;

        if (access_token) {
          console.log("access_token = " + access_token)
          console.log("refresh_token = " + refresh_token)

// {{ Some code here to store or leverage this access token }}

          res.redirect("/");
        }
      } catch (err) {
        console.log(`ERROR: ${err}`);
      }
    }
    return grabToken();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, your app can leverage this access_token you retrieved in the previous step, and use it as the value of the bearer token that your app will authorize any subsequent API requests to (for the particular resource the access token belongs to — e.g., &lt;a href="https://developers.miro.com/reference/api-reference" rel="noopener noreferrer"&gt;Miro REST API&lt;/a&gt;). This is step 4. Here is an example of a function that makes a request to the Miro REST API, using the access_token retrieved in the last step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import axios from "axios";

export default function handler(req, res) {
  const headers = {
    Accept: "application/json",
    "Content-Type": "application/json",
    Authorization: `Bearer ${access_token}`,
  };

  axios
    .get(
      "https://api.miro.com/v2/boards",
      {
        headers: headers,
      }
    )
    .then(function (response) {
      res.json(response.data);
    })
    .catch(function (error) {
      console.log(error);
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And lastly, it’s important to note that access tokens aren’t valid forever (technically, they can be — but this is not a best practice, and it’s &lt;a href="https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics" rel="noopener noreferrer"&gt;considered a security vulnerability to have non-expiring access tokens&lt;/a&gt;). A typical access_token is valid for some amount of time — usually 60 minutes — and then a new access token should be requested, using a refresh_token. (A refresh_token is typically returned alongside your original access_token in step 3, depending on your resource owner’s configuration settings.).&lt;/p&gt;

&lt;p&gt;While it’s admittedly a few steps end-to-end, it helps to visualize things a bit. Here’s a high-level overview of each of these 5 steps, and their interactions between the end user, an application, and the resource owner (&lt;em&gt;again, this could be Miro, Google, etc.&lt;/em&gt;).&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Master OAuth2.0 with Miro
&lt;/h2&gt;

&lt;p&gt;Interested in going deeper with OAuth2.0? Check out this on-demand educational training series, OAuth Essentials for Frontenders, linked above!&lt;/p&gt;

&lt;p&gt;And keep going with OAuth2.0, leveraging the &lt;a href="https://developers.miro.com/" rel="noopener noreferrer"&gt;Miro Developer Platform’s&lt;/a&gt; assortment of &lt;a href="https://github.com/miroapp/app-examples#rest-apis" rel="noopener noreferrer"&gt;sample apps&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;You can even &lt;a href="https://miro.com/app/dashboard/?createDevTeam=1" rel="noopener noreferrer"&gt;create a developer team&lt;/a&gt; and start quickly calling Miro’s REST APIs directly from our documentation. You can find the full &lt;a href="https://developers.miro.com/docs/rest-api-build-your-first-hello-world-app" rel="noopener noreferrer"&gt;Getting Started flow here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let us know what you build! We’re always happy to talk shop with fellow developers. 🙂&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Did you like learning more about OAuth2.0 and how to leverage the Miro Developer Platform? For more inspiration or questions, follow along with our &lt;a href="https://community.miro.com/developer-platform-and-apis-57" rel="noopener noreferrer"&gt;Developer Community&lt;/a&gt; on &lt;a href="https://www.youtube.com/channel/UC37GT5mtEbYmnxXlKTIJ-rw" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;, &lt;a href="https://github.com/miroapp/app-examples" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, and &lt;a href="https://discord.gg/9FUpabwXQK" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
    </item>
    <item>
      <title>Harnessing the power of React Server Components + Miro in NextJS</title>
      <dc:creator>William Bishop</dc:creator>
      <pubDate>Tue, 04 Oct 2022 12:49:58 +0000</pubDate>
      <link>https://forem.com/mirodevelopers/harnessing-the-power-of-react-server-components-miro-3h50</link>
      <guid>https://forem.com/mirodevelopers/harnessing-the-power-of-react-server-components-miro-3h50</guid>
      <description>&lt;p&gt;&lt;em&gt;This post was updated October 2023 to reflect the latest React Server Component capabilities.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  An in-depth look at React Server Components and how you can take advantage of this now stable feature using our NextJS starter app.
&lt;/h3&gt;

&lt;p&gt;With the introduction of React 18 in 2022, React Server Components (RSC) were initially introduced as an experimental feature. Since then, they've matured into a stable capability with a lot of great benefits. Follow along as we explore the basics of what React Server Components are, how to effectively build them in the context of our NextJS sample app, and what to expect from RSC in the near future as the capability continues to evolve!&lt;/p&gt;

&lt;p&gt;We’ll cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Benefits and limitations of RSC&lt;/li&gt;
&lt;li&gt;Quickstart: Writing a React Server Component&lt;/li&gt;
&lt;li&gt;Current and future state of RSC&lt;/li&gt;
&lt;li&gt;RSC x Miro (explore our sample app!)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  React Server Components: Why use them?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmattfeeohjeot4bipxxl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmattfeeohjeot4bipxxl.png" alt="Side-by-side comparison of frontend bundle size when leveraging MomentJS with RSC" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There’s a reason that React has invested time and resources developing React Server Components (and partnered with Vercel/NextJS): they’re efficient, in-demand by developers, and offer simple ways to improve the overall performance of any dependency-heavy application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html"&gt;React Server Components&lt;/a&gt; render server-side first. By rendering React components server-side first, it means we can enjoy each of the benefits below. 🤓&lt;/p&gt;

&lt;h4&gt;
  
  
  Improved performance
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Reduce the load time for apps with big bundles&lt;/li&gt;
&lt;li&gt;Since RSC are not included in the app bundle, they don’t contribute to its size, meaning smaller bundles and apps overall (see the MomentJS example above)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Direct access to your backend
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;RSC allow direct access to your backend and database, enabling fast data fetching&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  More dynamic than standard server side rendering
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;RSC can be re-fetched multiple times to re-render data (unlike traditional server side rendering, which typically happens once—on initialization)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Use them alongside client and shared components
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;You can use a mix of client side and server side components (denoted by their extension), as needed. &lt;a href="https://shopify.dev/custom-storefronts/hydrogen/framework/react-server-components"&gt;Shopify&lt;/a&gt; does a great job of visualizing this:
&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5hcdk279mtzc30malv2m.png" alt="Shopify Graphic" width="800" height="454"&gt;
(Source: Shopify, Custom Storefronts / Hydrogen / Framework / RSC)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As with any newer capability, there are going to be aspects that are continuing to evolve, or perhaps some unanswered questions about which direction things are headed in the future. We’ll call out what we &lt;strong&gt;do&lt;/strong&gt; know later on, but it’s a good time to be explicit about some current limitations (as of this writing):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Again, RSC are continuing to evolve, stay up to date on the latest in the official &lt;a href="https://nextjs.org/docs/app/building-your-application/rendering/server-components"&gt;NextJS documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;RSC are not intended for the interactivity that a typical frontend or set of client-side components would offer. They should be used thoughtfully, and aren’t an answer to all our frontend woes!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s strongly recommended to stick to the NextJS structure for leveraging RSC (instead of trying to create your own, standalone react server component bundles), due to the complexity and evolving nature of RSC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get your hands dirty
&lt;/h2&gt;

&lt;p&gt;With the stable release of RSC in NextJS, we decided to get our hands dirty and have some fun. &lt;/p&gt;

&lt;p&gt;And speaking of sticking to the NextJS structure/boilerplate for leveraging React Server Components, that’s exactly what we’ve done in our &lt;a href="https://github.com/miroapp/rsc-workshop/tree/moment-time"&gt;Miro app&lt;/a&gt;. In addition to testing out RSC, we wanted to add a little bit of our own twist to things. So, we created a Miro-inspired application that both helped us explore RSC and create a more visually robust app. As a bonus, we used Miro as our authorization provider in order to kill two birds with one stone. 😎&lt;/p&gt;

&lt;p&gt;You can clone the &lt;a href="https://github.com/miroapp/rsc-workshop/tree/moment-time"&gt;moment-time branch of our GitHub repo&lt;/a&gt; and start playing around. To get up and running:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clone the repo&lt;/li&gt;
&lt;li&gt;From the root, run &lt;code&gt;git checkout origin/moment-time&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;.env&lt;/code&gt; file with the following credentials:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MIRO_CLIENT_ID=""
MIRO_CLIENT_SECRET=""
MIRO_REDIRECT_URL="http://localhost:3000/auth/redirect/"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Reference the &lt;code&gt;README.md&lt;/code&gt; for steps to generate Miro Client ID and Miro Client Secret&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;npm install&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;npm run start&lt;/code&gt; and visit localhost:3000&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before diving into our starter app, you’ll want to make sure you’re up to speed with the basic conventions for writing react components, and it doesn’t hurt to review the official NextJS documentation on &lt;a href="https://nextjs.org/docs/app/building-your-application/rendering/server-components"&gt;React Server Components&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;By default, any components included in the &lt;code&gt;app&lt;/code&gt; directory of your NextJS app will be rendered on the server as React Server Components. See an example in our app's &lt;code&gt;page.tsx&lt;/code&gt; file, where we import a large package, MomentJS. But because this component is within the app directory, it will render server-side first and the frontend bundle size will remain untouched.&lt;/p&gt;

&lt;p&gt;You can also use client components within the &lt;code&gt;app&lt;/code&gt; directory, but you will need to be explicit about this in your component file. This requires the &lt;code&gt;use client&lt;/code&gt; directive to ensure the file is loaded client side. See an example of this in our &lt;a href="https://github.com/miroapp/rsc-workshop/blob/moment-time/app/TimeDifference.tsx"&gt;TimeDifference.tsx&lt;/a&gt; file, where we create a client component to show the change in time in realtime. This is an example of how you might use client components to complement server components — for situations where you want to add interactivity (think of timers, stock updates, flight details, etc.).&lt;/p&gt;

&lt;h3&gt;
  
  
  Write your first React Server Component
&lt;/h3&gt;

&lt;p&gt;Write your first React Server Component in NextJS, in just a few simple steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inside your NextJS project, navigate to the &lt;code&gt;app&lt;/code&gt; directory&lt;/li&gt;
&lt;li&gt;Create a new component&lt;/li&gt;
&lt;li&gt;Call this component from the main &lt;code&gt;index.js&lt;/code&gt; page (or if you're using our sample app, &lt;code&gt;page.tsx&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This component should render server-side first. To verify, load &lt;code&gt;page.tsx&lt;/code&gt; (or whatever page you wish to call the component in) and check out the page’s source code. You’ll see your server component reflected directly in the html markdown.&lt;/p&gt;

&lt;h3&gt;
  
  
  Miro Sample App
&lt;/h3&gt;

&lt;p&gt;Let’s take a look at a specific example in &lt;a href="https://github.com/miroapp/rsc-workshop/blob/moment-time/app/page.tsx"&gt;our sample app here&lt;/a&gt;. We’re leveraging the &lt;a href="https://www.npmjs.com/package/moment"&gt;moment.js NPM package&lt;/a&gt; to generate today’s date-time server-side. In our &lt;code&gt;page.tsx&lt;/code&gt; file, we’re importing MomentJS and returning it in our HTML.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// app/page.tsx
import moment from 'moment'
[...]

return (
  &amp;lt;div className="grid wrapper"&amp;gt;
    &amp;lt;time&amp;gt;
    {moment().format('MMMM Do YYYY, h:mm:ss a')}
    &amp;lt;/time&amp;gt;
  [...]
  &amp;lt;/div&amp;gt;
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And when we go to our app and inspect the page source, we’ll see our server component has been directly injected into the HTML on our frontend:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flxc8v9m3zheu2105xt7b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flxc8v9m3zheu2105xt7b.png" alt="Image description" width="800" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In contrast, when we look at &lt;code&gt;TimeDifference.tsx&lt;/code&gt; in our sample app, we are using the &lt;code&gt;use client&lt;/code&gt; directive at the top of the file to ensure the component is loaded client-side. You'll notice in the page source this is reflected as follows, since the time difference is rendered client-side:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1t4ao4xo9427ro40hljf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1t4ao4xo9427ro40hljf.png" alt="Image description" width="800" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Further exploration
&lt;/h3&gt;

&lt;p&gt;Okay, so we’ve talked a bit about RSC and we’ve seen how we’re using it in our &lt;a href="https://github.com/miroapp/rsc-workshop/tree/moment-time"&gt;Miro sample app&lt;/a&gt;—but this is just the tip of the iceberg!&lt;/p&gt;

&lt;p&gt;We’ve used the &lt;a href="https://www.npmjs.com/package/moment"&gt;MomentJS&lt;/a&gt; example to leverage RSC in our app, but there are other use cases that you can test out. Here are a couple of ideas to keep the momentum going:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new server component in our sample app that leverages a different dependency. For example, any larger NPM packages are great candidates to keep server-side!&lt;/li&gt;
&lt;li&gt;Take an existing or older React app of your own and groom through your components to see if you’re currently including any heavy dependencies on your frontend. If so, try and convert these to server-side components!&lt;/li&gt;
&lt;li&gt;Show us what you build!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The state of RSC: Now and next
&lt;/h2&gt;

&lt;p&gt;We’ve only scratched the surface of using React Server Components, but there’s so much more that can be done to leverage their efficient, performance-improving abilities. &lt;/p&gt;

&lt;p&gt;Luckily, the NextJS team thinks so too, so they’ve included it in their latest stable releases and we can look forward to more improvements in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the next big thing with NextJS and Miro
&lt;/h2&gt;

&lt;p&gt;If you found this quickstart on using React Server Components and our sample app helpful, let’s keep it going!&lt;/p&gt;

&lt;p&gt;Build any app or integration that leverages React + Miro’s &lt;a href="https://developers.miro.com/reference/api-reference"&gt;REST API&lt;/a&gt;, &lt;a href="https://developers.miro.com/docs/miro-web-sdk-introduction"&gt;Web SDK&lt;/a&gt;, or &lt;a href="https://developers.miro.com/docs/miro-live-embed-introduction"&gt;Live Embed&lt;/a&gt;, and share it with us on our developer community &lt;a href="https://discord.gg/NMnP3WwEbn"&gt;Discord server&lt;/a&gt;! &lt;/p&gt;

&lt;p&gt;Any functioning app that leverages one of these Miro capabilities is eligible to potentially be promoted more broadly in our community, and we’d love to share some exclusive Miro swag with you. 🚀&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yxqedzjxqmhn03dfz2r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yxqedzjxqmhn03dfz2r.png" alt="Sample Apps Graphic" width="800" height="418"&gt;&lt;/a&gt;&lt;br&gt;
Check out our other &lt;a href="https://github.com/miroapp/app-examples"&gt;sample apps&lt;/a&gt; for some more inspiration. We can’t wait to see what you build!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Did you like seeing how you can leverage the Miro Developer Platform in conjunction with React? For more inspiration or questions, follow along with our &lt;a href="https://community.miro.com/developer-platform-and-apis-57"&gt;Developer Community&lt;/a&gt; on &lt;a href="https://www.youtube.com/channel/UC37GT5mtEbYmnxXlKTIJ-rw"&gt;YouTube&lt;/a&gt;, &lt;a href="https://github.com/miroapp/app-examples"&gt;GitHub&lt;/a&gt;, and &lt;a href="https://discord.gg/NMnP3WwEbn"&gt;Discord&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>miro</category>
      <category>nextjs</category>
      <category>rest</category>
    </item>
  </channel>
</rss>
