<?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: Stevo Perisic</title>
    <description>The latest articles on DEV Community by Stevo Perisic (@stevoperisic).</description>
    <link>https://dev.to/stevoperisic</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%2F105474%2Ff67aaad7-3ffb-4b1a-a66b-72fb0970ae6a.png</url>
      <title>DEV Community: Stevo Perisic</title>
      <link>https://dev.to/stevoperisic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stevoperisic"/>
    <language>en</language>
    <item>
      <title>Building a JAMStack App with Eleventy.js, CloudFlare Workers and AthenaHealth APIs - Part 2</title>
      <dc:creator>Stevo Perisic</dc:creator>
      <pubDate>Sun, 12 Jan 2025 18:51:20 +0000</pubDate>
      <link>https://dev.to/stevoperisic/building-a-jamstack-app-with-eleventyjs-cloudflare-workers-and-athenahealth-apis-part-2-2h32</link>
      <guid>https://dev.to/stevoperisic/building-a-jamstack-app-with-eleventyjs-cloudflare-workers-and-athenahealth-apis-part-2-2h32</guid>
      <description>&lt;h2&gt;
  
  
  Recap of Part one
&lt;/h2&gt;

&lt;p&gt;In part 1 we focused on creating a simple JAMStack application that fetches and caches data from the AthenaHealth API using CloudFlare Workers. We developed the app to include paths for fetching department and provider information, demonstrating the seamless integration between CloudFlare Workers and AthenaHealth APIs to deliver an efficient and scalable JAMStack application.&lt;/p&gt;

&lt;p&gt;We developed a CloudFlare Worker that fetches and serves a list of healthcare providers from the AthenaHealth API, which can be accessed at &lt;a href="https://jamstack.perisicdesigns.workers.dev/providers" rel="noopener noreferrer"&gt;https://jamstack.perisicdesigns.workers.dev/providers&lt;/a&gt;.&lt;br&gt;
As we progress to the next stage, our objective is to create an engaging, simple and user-friendly interface for patients to view this information. To achieve this, we will utilize CloudFlare Pages, a powerful JAMStack solution, in combination with Eleventy.js, a static site generator. This approach enables us to build a fast, secure, and easily maintainable website, while also enhancing the user experience. By leveraging the capabilities of CloudFlare Pages and Eleventy.js, we will bring the data retrieved by our CloudFlare Worker to life and deliver a seamless, responsive experience for patients accessing the list of providers.&lt;/p&gt;
&lt;h2&gt;
  
  
  Environment Set-up
&lt;/h2&gt;

&lt;p&gt;To publish a website to CloudFlare Pages using Eleventy and GitHub, there are several essential steps you must follow to prepare the environment. First, ensure that Node and npm  are installed on your local machine, as Eleventy depends on these tools. You can verify the installation by running &lt;code&gt;node -v&lt;/code&gt; and &lt;code&gt;npm -v&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, create a new GitHub repository to host your project's source code. Then, install Eleventy.js globally on your system using &lt;code&gt;npm install -g @11ty/eleventy&lt;/code&gt;. After that, initiate a new Eleventy project within your GitHub repository by running the appropriate commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir your-project-name
cd your-project-name
npm init -y
npm install --save-dev @11ty/eleventy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, set up the file structure for the project and create the initial files. You can refer to this GitHub repository for an example of the necessary setup: &lt;a href="https://github.com/stevoPerisic/jamstack-pages-athenaHealth" rel="noopener noreferrer"&gt;                          &lt;/a&gt;&lt;a href="https://github.com/stevoPerisic/jamstack-pages-athenaHealth" rel="noopener noreferrer"&gt;https://github.com/stevoPerisic/jamstack-pages-athenaHealth&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Files Breakdown
&lt;/h2&gt;

&lt;p&gt;Here is a brief explanation of what each file does:&lt;/p&gt;

&lt;h3&gt;
  
  
  _includes/base.njk
&lt;/h3&gt;

&lt;p&gt;This file is a Nunjucks template that forms the foundation of our website. It provides the core HTML structure, which comprises the head and body sections, and ensures that the Bootstrap CSS and JavaScript files are properly linked. The &lt;code&gt;{{ content | safe }}&lt;/code&gt; line acts as a versatile placeholder, allowing content from other templates to be seamlessly integrated into the overall layout. This base template enables a consistent design and structure throughout the website while still allowing for the flexibility to accommodate diverse content.&lt;/p&gt;

&lt;h3&gt;
  
  
  theme.css and hs-mega-menu.min.css
&lt;/h3&gt;

&lt;p&gt;These two CSS files serve distinct purposes within the website. The theme.css file contains the overall styling for the website, ensuring that its visual elements are consistent and appealing. On the other hand, hs-mega-menu.min.css focuses specifically on the menu's styling, providing a polished and functional navigation experience for users. Both of these files are linked within the _includes/base.njk file, ensuring they are properly loaded and applied throughout the site.&lt;/p&gt;

&lt;h3&gt;
  
  
  _data/providers.js file.
&lt;/h3&gt;

&lt;p&gt;This file is essentially a JavaScript module that fetches a list of providers from an API endpoint and assigns random headshots to each provider using the randomuser.me API. It starts by importing the cross-fetch library to enable fetch in both browser and node environments. The getRandomHeadshot function is defined to fetch random user data, including headshots, from the randomuser.me API and return an array of headshot URLs. The main function fetches a list of providers, filters them to only include providers of type "Person," and calls the getRandomHeadshot function to obtain headshots for the filtered providers. Finally, it creates a new array of provider objects with an added headshotUrl property and returns the array as the module's output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fetch = require('cross-fetch');

async function getRandomHeadshot(num) {
    const response = await fetch(`https://randomuser.me/api/?results=${num}`);
    const data = await response.json();
    const headshots = data.results.map(user =&amp;gt; user.picture.large);
    return headshots;
}

module.exports = async function () {
    const response = await fetch("https://jamstack.perisicdesigns.workers.dev/providers");
    const data = await response.json();
    const providers = data.providers.filter(provider =&amp;gt; provider.entitytype === "Person");
    const headshots = await getRandomHeadshot(providers.length);
    const providersWithHeadshots = providers.map((provider, index) =&amp;gt; {
        return {
            ...provider,
            headshotUrl: headshots[index % headshots.length],
        };
    });
    return providersWithHeadshots;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  _eleventy.js
&lt;/h3&gt;

&lt;p&gt;This is a configuration file that plays a crucial role in customizing the Eleventy build process for our specific needs. In this snippet, the &lt;code&gt;eleventyConfig.addPassthroughCopy()&lt;/code&gt; function is used twice to ensure that the 'css' and 'js' directories are copied directly into the output folder during the build process, without any modifications. This allows for static assets, such as stylesheets and JavaScript files, to be served correctly when the site is live. The 'return' statement defines the configuration object, specifying the input directory as '.', which is the root directory containing the Eleventy files. It also sets the 'includes' directory to '_includes', the location where template files like 'base.njk' are stored. This configuration ensures that Eleventy knows where to find the necessary files and directories during the build process, allowing for a smooth and efficient development experience.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = function (eleventyConfig) {

    eleventyConfig.addPassthroughCopy("css");
    eleventyConfig.addPassthroughCopy("js");

    return {
        dir: {
            input: ".", // The root directory for your Eleventy files
            includes: "_includes", // The directory where your includes (like 'base.njk') are located
            // ... other configuration properties
        },
    };
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  index.njk
&lt;/h3&gt;

&lt;p&gt;This file is an Eleventy template file that defines the structure and content for the "Providers" page of the website. It begins with front matter that specifies the base layout as 'base.njk' and sets the page title to "Providers".&lt;/p&gt;

&lt;p&gt;Within the HTML, a container and row classes are used to establish a responsive grid layout. The 'title' variable, set in the front matter, is displayed as an 'h2' heading. The main content of the page consists of a loop that iterates through each 'provider' object in the 'providers' array.&lt;/p&gt;

&lt;p&gt;For each provider, a column is created containing an image with the provider's headshot, their first and last name as an 'h5' heading, their provider type, and a link to the provider's details page. The loop ends after all providers have been processed, and the resulting layout will display a responsive grid of provider cards with relevant information and links to individual provider pages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
layout: base.njk
title: Providers
---
&amp;lt;div class="container"&amp;gt;
    &amp;lt;div class="row"&amp;gt;
        &amp;lt;!-- Team --&amp;gt;
        &amp;lt;div class="container content-space-1"&amp;gt;
            &amp;lt;!-- Heading --&amp;gt;
            &amp;lt;div class="w-lg-65 text-center mx-lg-auto mb-5 mb-sm-7 mb-lg-10"&amp;gt;
                &amp;lt;h2&amp;gt;{{ title }}&amp;lt;/h2&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;!-- End Heading --&amp;gt;
            &amp;lt;div class="row row-cols-1 row-cols-sm-2 row-cols-lg-3"&amp;gt;
                {% for provider in providers %}

                    &amp;lt;div class="col mb-10"&amp;gt;
                        &amp;lt;!-- Team --&amp;gt;
                        &amp;lt;div class="w-sm-65 text-center mx-auto"&amp;gt;
                            &amp;lt;img class="img-fluid rounded-3 mb-4"
                                 src="{{ provider.headshotUrl }}"
                                 alt="{{ provider.firstname }} {{ provider.lastname }}"&amp;gt;
                            &amp;lt;h5 class="mb-1"&amp;gt;{{ provider.firstname }} {{ provider.lastname }}&amp;lt;/h5&amp;gt;
                            &amp;lt;span class="d-block"&amp;gt;{{ provider.providertype }}&amp;lt;/span&amp;gt;
                            &amp;lt;span class="d-block"&amp;gt;
                                &amp;lt;a href="/provider/{{ provider.providerid }}"&amp;gt;View Details&amp;lt;/a&amp;gt;
                            &amp;lt;/span&amp;gt;
                        &amp;lt;/div&amp;gt;
                        &amp;lt;!-- End Team --&amp;gt;
                    &amp;lt;/div&amp;gt;
                &amp;lt;!-- End Col --&amp;gt;
                {% endfor %}
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  provider.njk
&lt;/h3&gt;

&lt;p&gt;This is another template file. It is used to display the details of a specific healthcare provider. It uses the base layout defined in the base.njk file and sets the title as "Provider Details." The file also utilizes Eleventy's pagination feature to generate individual pages for each provider.&lt;/p&gt;

&lt;p&gt;The pagination configuration in the front matter specifies the providers data collection as the data source, sets the page size to 1 to create a separate page for each provider, and assigns the current provider data to an alias named provider. The permalink configuration generates a unique URL for each provider page based on their providerid.&lt;/p&gt;

&lt;p&gt;Inside the main content area, the template uses the Bootstrap framework to create a responsive layout displaying the provider's profile. The profile includes the provider's headshot, name, and provider type. A sample description text (Lorem ipsum) is added as a placeholder for any additional information about the provider. At the bottom, a "Follow" button is included, which can be customized to implement a follow functionality.&lt;/p&gt;

&lt;p&gt;The template employs Eleventy's Nunjucks templating engine to output dynamic content using double curly braces, such as &lt;code&gt;{{ provider.headshotUrl }}&lt;/code&gt;, &lt;code&gt;{{ provider.firstname }}&lt;/code&gt;, and &lt;code&gt;{{ provider.lastname }}&lt;/code&gt;. This allows the template to be rendered with the specific data for each provider, resulting in personalized pages for every individual in the providers data collection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
layout: base.njk
title: Provider Details
pagination:
data: providers
size: 1
alias: provider
permalink: /provider/{{ provider.providerid }}/
--
&amp;lt;!-- User Profile --&amp;gt;
    &amp;lt;div class="container content-space-1"&amp;gt;
        &amp;lt;div class="row justify-content-md-center"&amp;gt;
            &amp;lt;div class="col-md-8"&amp;gt;
                &amp;lt;div class="text-center"&amp;gt;
                    &amp;lt;img class="avatar avatar-xxl avatar-circle mb-3"
                         src="{{ provider.headshotUrl }}" alt="{{ provider.firstname }} {{ provider.lastname }}"&amp;gt;

                    &amp;lt;div class="mb-4"&amp;gt;
                        &amp;lt;h3&amp;gt;{{ provider.firstname }} {{ provider.lastname }}&amp;lt;/h3&amp;gt;
                        &amp;lt;span class="d-block mb-1"&amp;gt;{{ provider.providertype }}&amp;lt;/span&amp;gt;
                        &amp;lt;p&amp;gt;
                            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ornare turpis quis dui accumsan,
                            sit amet vehicula velit blandit. Nam porttitor dolor a nulla pulvinar, vitae commodo quam luctus.
                            Suspendisse potenti. Pellentesque habitant morbi tristique senectus et netus et malesuada fames
                            ac turpis egestas. Cras ac mollis est. Sed accumsan ante sed pharetra facilisis. Curabitur
                            porttitor risus consectetur faucibus egestas.
                        &amp;lt;/p&amp;gt;
                    &amp;lt;/div&amp;gt;

                    &amp;lt;button type="button" class="btn btn-outline-primary btn-sm"&amp;gt;
                        &amp;lt;i class="bi-person-plus-fill me-1"&amp;gt;&amp;lt;/i&amp;gt; Follow
                    &amp;lt;/button&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;!-- End Col --&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;!-- End Row --&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;!-- End User Profile --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The .gitignore file update
&lt;/h2&gt;

&lt;p&gt;The .gitignore file is a configuration file used by Git to determine which files and directories should not be tracked by the version control system. In other words, the files and directories listed in the .gitignore file will be ignored when committing changes to the Git repository.&lt;/p&gt;

&lt;p&gt;In the case of an Eleventy project, the generated site files are typically placed in a folder named _site by default. These files are the result of Eleventy processing your templates and data, and they represent the static output of your website. Since these files are generated automatically during the build process, there's no need to track them in the Git repository. Tracking the generated files could lead to unnecessary conflicts and clutter in the version control history.&lt;/p&gt;

&lt;p&gt;By adding _site (or the appropriate folder name) to the .gitignore file, you ensure that the generated site files are not tracked by Git, keeping your repository clean and focused on the source files required to build your Eleventy project. This also prevents any potential issues when deploying the site using services like CloudFlare Pages, as these services will build and deploy the site from the source files in the Git repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying to CloudFlare Pages
&lt;/h2&gt;

&lt;p&gt;With our project set up, we can proceed to deploy it to CloudFlare Pages. First, push your project to a new GitHub repository. Next, sign in to your CloudFlare account and navigate to the CloudFlare Pages dashboard. Click "Create a project" and select the GitHub repository you just pushed. To configure the build settings, set the build command to eleventy and the build output directory to _site. Then, click "Begin setup" followed by "Save and deploy". CloudFlare Pages will build and deploy your site, and once the deployment is complete, you can visit your site using the provided URL. In our case we have the result deployed to &lt;a href="https://jamstack-pages-athenahealth.pages.dev/" rel="noopener noreferrer"&gt;https://jamstack-pages-athenahealth.pages.dev/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;In this comprehensive tutorial, we began by building a JAMstack application using Cloudflare Workers and AthenaHealth APIs. The app fetches data from the Departments and Providers APIs and displays a JSON data response using separate paths in the worker. With this foundation in place, we continued to use the JAMStack approach to create an appealing User Interface, displaying our data in a more attractive way for our users.&lt;/p&gt;

&lt;p&gt;Furthermore, we guided you through the process of creating JAMStack pages using CloudFlare Pages, Eleventy.js, and Bootstrap 5. We demonstrated how to set up the project environment, configure Eleventy, create the necessary files, and deploy the website to CloudFlare Pages. By following these steps, you can create your own JAMStack website and leverage the benefits of modern web development technologies for faster, more secure, and scalable web applications. This tutorial provides a solid foundation for you to build upon, allowing you to create engaging and efficient web applications with ease.&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>jamstack</category>
      <category>cloudflare</category>
      <category>athenahealth</category>
      <category>healthtech</category>
    </item>
    <item>
      <title>Building a JAMStack App with Eleventy.js, CloudFlare Workers and AthenaHealth APIs - Part 1</title>
      <dc:creator>Stevo Perisic</dc:creator>
      <pubDate>Sun, 12 Jan 2025 17:21:29 +0000</pubDate>
      <link>https://dev.to/stevoperisic/building-a-jamstack-app-with-eleventyjs-cloudflare-workers-and-athenahealth-apis-part-1-4chi</link>
      <guid>https://dev.to/stevoperisic/building-a-jamstack-app-with-eleventyjs-cloudflare-workers-and-athenahealth-apis-part-1-4chi</guid>
      <description>&lt;p&gt;In part one of this two-post blog entry, we will walk through the process of creating a JAMStack application using CloudFlare Workers and AthenaHealth APIs. We will build a simple app that fetches data from the AthenaHealth API, caches the data, and displays it using CloudFlare Workers. &lt;/p&gt;




&lt;h2&gt;
  
  
  What is JAMStack?
&lt;/h2&gt;

&lt;p&gt;JAMstack is a modern web development architecture focused on improving performance, scalability, and security. The acronym JAM stands for JavaScript, APIs, and Markup. The key principles of JAMstack are pre-rendering static assets, leveraging client-side JavaScript for interactivity, and utilizing APIs for server-side functionality.&lt;/p&gt;

&lt;p&gt;In a JAMstack application, content is generated during the build process, creating static files that can be served directly from a Content Delivery Network (CDN). This approach reduces server load and latency, resulting in faster page load times and better user experience. The client-side JavaScript is responsible for dynamic behavior, making API calls to access data or perform server-side operations.&lt;/p&gt;

&lt;p&gt;JAMstack promotes a decoupled architecture, which separates the frontend from the backend, enabling developers to use the best tools and technologies for each. This also simplifies the deployment process and makes scaling the application easier. JAMstack sites are inherently more secure, as there are fewer attack vectors due to the reduced reliance on server-side components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of Cloudflare Workers and AthenaHealth APIs
&lt;/h2&gt;

&lt;p&gt;Cloudflare Workers is a serverless platform that allows you to build and deploy applications at the edge. It enables developers to write JavaScript code that runs directly in Cloudflare's global network of data centers, ensuring low latency and high performance. The Cloudflare Workers documentation provides a comprehensive guide, including detailed API references, examples, and tutorials to help you get started and make the most of the platform.&lt;/p&gt;

&lt;p&gt;AthenaHealth provides a suite of APIs to access and interact with healthcare data. In this tutorial, we will use the Departments API &lt;a href="https://docs.athenahealth.com/api/api-ref/departments#Departments" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://docs.athenahealth.com/api/api-ref/departments#Departments" rel="noopener noreferrer"&gt;https://docs.athenahealth.com/api/api-ref/departments#Departments&lt;/a&gt; and the Providers API&lt;br&gt;
 &lt;a href="https://docs.athenahealth.com/api/api-ref/provider#Provider" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://docs.athenahealth.com/api/api-ref/provider#Provider" rel="noopener noreferrer"&gt;https://docs.athenahealth.com/api/api-ref/provider#Provider&lt;/a&gt; to fetch and display information about departments and providers.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up Cloudflare Workers
&lt;/h2&gt;

&lt;p&gt;To get started, sign up for a Cloudflare account if you don't already have one. Next, follow the instructions in the Cloudflare Workers documentation &lt;a href="https://developers.cloudflare.com/workers" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://developers.cloudflare.com/workers" rel="noopener noreferrer"&gt;https://developers.cloudflare.com/workers&lt;/a&gt; to set up your environment and create your first worker.&lt;/p&gt;
&lt;h2&gt;
  
  
  Authenticating with AthenaHealth APIs
&lt;/h2&gt;

&lt;p&gt;Before you can access the AthenaHealth APIs, you need to authenticate and obtain an access token. We will create a function called &lt;code&gt;authenticate()&lt;/code&gt; that handles the authentication process, making a POST request to the API with the client credentials and returning the access token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function authenticate() {
    const url = `${ATHENA_BASE_URL}${AUTH_PATH}`;
    const auth = 'Basic ' + btoa(ATHENA_API_KEY + ':' + ATHENA_API_SECRET);
    const headers = new Headers({
        'Authorization': auth,
        'Content-Type': 'application/x-www-form-urlencoded',
    });
    const body = new URLSearchParams({
        grant_type: 'client_credentials',
        scope: 'athena/service/Athenanet.MDP.*',
    });

    const response = await fetch(url, { method: 'POST', headers, body });
    const json = await response.json();

    if (!json.access_token) {
        throw new Error('Missing token!');
    }

    return json.access_token;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fetching and Caching Data from AthenaHealth APIs
&lt;/h2&gt;

&lt;p&gt;With the access token in hand, we can now fetch data from the Departments and Providers APIs. We will create two functions, &lt;code&gt;fetchAthenaDepartments()&lt;/code&gt; and &lt;code&gt;fetchAthenaProviders()&lt;/code&gt;, which will handle the process of fetching the data and caching it using Cloudflare Workers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function fetchAthenaDepartments(token) {
    const url = `${ATHENA_BASE_URL}/v1/${PRACTICE_ID}/departments`;
    const headers = new Headers({
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json',
    });

    const response = await fetch(url, { headers });
    return response.json();
}

async function fetchAthenaProviders(token) {
    const url = `${ATHENA_BASE_URL}/v1/${PRACTICE_ID}/providers`;
    const headers = new Headers({
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json',
    });

    const response = await fetch(url, { headers });
    return response.json();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating Paths for Departments and Providers
&lt;/h2&gt;

&lt;p&gt;In our Cloudflare worker, we will create paths for fetching department and provider information. Update the fetch function in the worker to handle the &lt;code&gt;/departments&lt;/code&gt; and &lt;code&gt;/providers&lt;/code&gt; paths, as well as a separate path for fetching a specific provider by ID, &lt;code&gt;/provider/[id]&lt;/code&gt;.&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 {
    async fetch(request, env, ctx) {
        const url = new URL(request.url);

        if (url.pathname === '/departments') {
            try {
                const token = await authenticate();
                const departments = await fetchAthenaDepartments(token);
                return new Response(JSON.stringify(departments), {
                    headers: { 'Content-Type': 'application/json' },
                });
            } catch (error) {
                return new Response(error.message, { status: 500 });
            }
        }
        else if (url.pathname === '/providers') {
            try {
                const token = await authenticate();
                const providers = await fetchAthenaProviders(token);
                return new Response(JSON.stringify(providers), {
                    headers: { 'Content-Type': 'application/json' },
                });
            } catch (error) {
                return new Response(error.message, { status: 500 });
            }
        }
        else {
            return new Response('Not Found', { status: 404 });
        }
    },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Testing the Worker
&lt;/h2&gt;

&lt;p&gt;To test the worker, you can use the wrangler command-line tool that comes with Cloudflare Workers. Run &lt;code&gt;npx wrangler dev src/index.js&lt;/code&gt; in your terminal to start a development server, and open a browser tab at &lt;code&gt;&lt;a href="http://localhost:8787/" rel="noopener noreferrer"&gt;http://localhost:8787/&lt;/a&gt;&lt;/code&gt; to see your worker in action.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying the Worker
&lt;/h2&gt;

&lt;p&gt;Finally, to deploy your worker, run &lt;code&gt;npx wrangler publish src/index.js --name my-worker&lt;/code&gt; in your terminal.&lt;/p&gt;




&lt;p&gt;In this tutorial, we started working on a JAMstack application using Cloudflare Workers and AthenaHealth APIs. The app, so far, fetches data from the Departments and Providers APIs and displays a JSON data response using separate paths in the worker. With this foundation in place, we will next start using the JAMStack approach to create a UI and display our data to our users in a more attractive way.&lt;/p&gt;

</description>
      <category>jamstack</category>
      <category>cloudflare</category>
      <category>athenahealth</category>
      <category>healthtech</category>
    </item>
    <item>
      <title>Dynamic Dockerfile with ARG</title>
      <dc:creator>Stevo Perisic</dc:creator>
      <pubDate>Wed, 03 Oct 2018 19:12:40 +0000</pubDate>
      <link>https://dev.to/stevoperisic/dynamic-dockerfile-with-arg-2h62</link>
      <guid>https://dev.to/stevoperisic/dynamic-dockerfile-with-arg-2h62</guid>
      <description>

&lt;p&gt;Sometimes you have a need for a dynamic Dockerfile. For example, you are running a microservice the requires different API calls per environment: dev, staging and production. If your service depends on environment variables to make a distinction of which API to call you usually set those in the Dockerfile using the:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENV environment=production
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's all fine, however, what do we do if &lt;code&gt;environment&lt;/code&gt; needs to change based on the build destination? You would have to manually update the Dockerfile before each build.&lt;/p&gt;

&lt;p&gt;We can use the ARG variable instead and update the value of &lt;code&gt;environment&lt;/code&gt; ad build time. Consider the following:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ARG environment
ENV environment=${environment:-production} // set a default in case the ARG isn't passed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What we've done above is declared a build argument &lt;code&gt;environment&lt;/code&gt;, then used that value to populate the ENV variable environment in the Docker build image. Consider the following build command:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t myTag --build-arg environment=staging
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In this case we first take the value of the build argument, than pass its value down to the ENV variable so that it will evaluate to "staging". However if we don't specify the build arguments and simply run:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t myTag
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then the value of &lt;code&gt;ENV environment&lt;/code&gt; will be "production" as we've set for our default value.&lt;/p&gt;

&lt;p&gt;This helps immensely when you have more than 2 environments to build to and have to support different server side renders or API calls that are tightly coupled with those environments.&lt;/p&gt;

&lt;p&gt;For more details checkout &lt;a href="https://docs.docker.com/engine/reference/builder/#using-arg-variables"&gt;Docker docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;


</description>
      <category>docker</category>
      <category>dockerfile</category>
      <category>arg</category>
      <category>buildarg</category>
    </item>
    <item>
      <title>Installing Python3, Pip and AWS CLI on macOS Sierra</title>
      <dc:creator>Stevo Perisic</dc:creator>
      <pubDate>Wed, 03 Oct 2018 17:34:16 +0000</pubDate>
      <link>https://dev.to/stevoperisic/installing-python3-pip-and-aws-cli-on-macos-sierra-3pea</link>
      <guid>https://dev.to/stevoperisic/installing-python3-pip-and-aws-cli-on-macos-sierra-3pea</guid>
      <description>

&lt;p&gt;A quick guide to installing Python v3, Pip package manager and the AWS CLI on the Mac OS Sierra. This write up assumes you only have Python 2.7 that came pre-installed on the Mac and Homebrew installed. If you need Homebrew please visit &lt;a href="https://brew.sh/"&gt;https://brew.sh/&lt;/a&gt; and get it than come back here for the rest of the guide.&lt;/p&gt;

&lt;p&gt;First let’s get Python 3 installed by running (If you had Homebrew installed it might update when you call the install command as it did for me. you might need to re-run the below install command.):&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;code&gt;~ brew install python3&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;At this point, you have the system Python 2.7 available and the Homebrew version of Python 3 as well. Launch the system Python 2.7 using &lt;code&gt;~ python&lt;/code&gt; and Pyhton 3 using &lt;code&gt;~ python3&lt;/code&gt; commands respectively.&lt;/p&gt;

&lt;p&gt;You’ll be able to start Pip 3 using the &lt;code&gt;~ pip3&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;Now let’s install AWS CLI.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;code&gt;~ pip3 install awscli --upgrade --user&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Verify the install using:&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;code&gt;~ aws --version&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;In my case I had to add the Python 3 location to the $PATH variable, you might have to do it also. Here’s how:&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;code&gt;~ export PATH=~/Library/Python/3.6/bin:$PATH&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Check the aws install one more time:&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;code&gt;~ aws --version&lt;br&gt;
aws-cli/1.11.185 Python/3.6.3 Darwin/16.7.0 botocore/1.7.43&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Now you should be all set :)&lt;/p&gt;

&lt;p&gt;You will have to set up the credentials within the AWS CLI, you can get those values from the “My Security Credentials” menu link under your username in the Amazon dashboard.&lt;/p&gt;

&lt;p&gt;—&lt;/p&gt;

&lt;p&gt;Just in case you need them, here are some references:&lt;/p&gt;

&lt;p&gt;&lt;a href="docs.python-guide.org"&gt;Installing Python 3 on Mac OS X - The Hitchhiker's Guide to Python&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="docs.aws.amazon.com"&gt;Install the AWS Command Line Interface on macOS - AWS Command Line Interface&lt;/a&gt;&lt;/p&gt;


</description>
      <category>python3</category>
      <category>pip</category>
      <category>awscli</category>
      <category>machinelearning</category>
    </item>
  </channel>
</rss>
