<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[TakeShape]]></title><description><![CDATA[TakeShape's API Mesh enables front-end developers to harness the power of the Jamstack. Reduce complexity and ship faster.]]></description><link>https://hashnode.takeshape.io</link><generator>RSS for Node</generator><lastBuildDate>Fri, 22 May 2026 11:55:43 GMT</lastBuildDate><atom:link href="https://hashnode.takeshape.io/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[The Jamstack Identity Crisis: an Even-Handed Overview]]></title><description><![CDATA[The community is abuzz.
The last few months, we've been debating — as a community — what the Jamstack even is. In the way of a quick summary, we largely split into two groups:

The Pragmatists
 This group, pioneered by people like Hashicorp advocate ...]]></description><link>https://hashnode.takeshape.io/the-jamstack-identity-crisis-an-even-handed-overview</link><guid isPermaLink="true">https://hashnode.takeshape.io/the-jamstack-identity-crisis-an-even-handed-overview</guid><category><![CDATA[JAMstack]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Jaden Baptista]]></dc:creator><pubDate>Thu, 19 Aug 2021 15:21:19 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1629386311363/kibNxbhWJ.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The community is abuzz.</p>
<p>The last few months, we've been debating — as a community — what the Jamstack even is. In the way of a quick summary, we largely split into two groups:</p>
<ol>
<li><p><strong>The Pragmatists</strong></p>
<p> This group, pioneered by people like Hashicorp advocate Jeff Escalante, Forestry developer Franck Taillander, and Layer0 CTO Ishan Anand, is pushing to drop the name Jamstack because it's growing increasingly pointless as a descriptive term. They believe its trendiness has worn off and it's becoming restrictive and ultimately vexing as we fight about what's included in the definition.</p>
</li>
<li><p><strong>The Resolutionists</strong></p>
<p> On the other side of the aisle, you've got the folks who want to fix the definition of the Jamstack to include new practices rather than ditch it altogether. In this camp, you've got industry leaders like Bud Parr of the New Dynamic, Brian Rinaldi from StepZen, CloudCannon CEO Mike Neumegen (who wrote an excellent article on this just a few days ago by the way), and the king of performance and accessibility Henri Helvetica.</p>
</li>
</ol>
<p>So far, we've been trying to place a clear border through a fuzzy gradient. We've been asking: "where do we draw the line between Jamstack and the other?"</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1629386409470/I8kLzogo4.gif" alt="consensus on the Jamstack GIF" /></p>
<p>We're starting to see a consensus, though. Attitudes are cooling and people are starting to come together on a solution. Here's the gist of what they're agreeing on:</p>
<h2 id="the-jamstack-as-a-set-of-best-practices">The Jamstack as a set of best practices.</h2>
<p>It's not a dichotomy anymore. The question is no longer, "is this site Jamstack?" The question is now, "how many Jamstack techniques does this site incorporate?" </p>
<p>That undercuts the whole premise of the earlier debate. If the Jamstack is no longer a restrictive and exclusive category, then you don't have to drop the name entirely to start using some non-Jamstack techniques like dynamic rendering on a monolithic server. You also don't need to redefine the Jamstack to start doing bigger and better things, because you can use the Jamstack label to talk about <em>some</em> of your site without sounding like a purist. Now, we don't need to draw a clear border through a fuzzy gradient, trying to separate Jamstack from the other. We don't even have to place our site on that spectrum at all.</p>
<p>Here are some of those principles:</p>
<ol>
<li>Jamstack sites don't rely on dynamic page-building code on the server.</li>
<li>As much content as possible is baked into the markup at build time.</li>
<li>Extra functionality is primarily added with third-party APIs.</li>
<li>Any necessary custom server-side code is organized in manageable, atomic, decoupled microservices.</li>
<li>Most of the necessary assets for the site to load are held close to the client in a CDN.</li>
</ol>
<p>Perhaps you are prerendering most of your site, but the backend API you've created for yourself is based around a monolithic architecture because your particular use case requires it. That doesn't have to be controversial! You've just used some Jamstack techniques in combination with some more traditional techniques to create an application that works best for you. We can all agree that a hybrid approach like this will — in many but not all situations — work better than either extreme, right?</p>
<h2 id="consensus-is-goodright">Consensus is good...right?</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1629386422300/EszI7ucIF.gif" alt="Consensus GIF from the article linked below" /></p>
<p>From one point of view, absolutely! People who were, at one point, not seeing eye to eye are now cooperating, and that sure is lovely to see.</p>
<p>On the other hand, one of our favorite business articles over here at TakeShape, a 2016 post on the blog "Conferences that Work" entitled <a target="_blank" href="https://www.conferencesthatwork.com/index.php/facilitation/2016/11/when-consensus-is-dangerous/">"When consensus is dangerous"</a>, makes a great point:</p>
<h3 id="the-value-of-consensus-is-in-the-process-of-seeking-it-not-a-yes-we-have-consensus-outcome">"The value of consensus is in the <em>process</em> of seeking it — not a “yes, we have consensus!” outcome."</h3>
<p>It's the old adage "it's the journey, not the destination" playing itself out over again. If we focus on the outcome of what the community largely feels the Jamstack is, we might be missing the underlying lesson. This whole ordeal just goes to prove that the people who are participating in this discussion are doing so because they have a passion for whatever they feel the name "Jamstack" represents. That's what's really binding this otherwise heterogenous and diverse community together!</p>
<h2 id="so-lets-find-something-new-to-argue-about">So let's find something new to argue about.</h2>
<p>At the Jamstack Philly: Summer of Jamstack event that we organized on July 1 and August 4, 2021, the closing keynote argued that we'll see the next few years of Jamstack development marked by four major trends:</p>
<ol>
<li>We'll take Astro's motto to heart and start seriously shipping less JavaScript. That means going back to the simplicity and bare-bones, lightweight structure of the first Jamstack tools (like Jekyll) while retaining all the functionality of the big platforms that came later (like Next.JS).</li>
<li>We'll help non-developers to work with us on equal footing, finding ways to get them interacting with us in the same tools and codebases with clever and intuitive GUIs.</li>
<li>We'll see tools that we've come to love like Netlify or Vercel start to separate from the pack with platform-specific features in order to stay relevant.</li>
<li>We'll adopt new terminology for the newest techniques we're using (for example, DPR) that are far less specific — in other words, get rid of that spectrum entirely. Some are suggesting calling it just "modern" development.</li>
</ol>
<p>Let's talk about those! Let's ask new questions to keep the process of consensus going:</p>
<ol>
<li>How far can we push HTML and CSS (and WASM?) to replace the need for the slow and burdensome JavaScript?</li>
<li>What tools can we create to remove the encumbrances of our non-developer colleagues and help them work with us on the same plane?</li>
<li>If platforms have to innovate independently to stay in business, how can they maintain the cross-platform values that the Jamstack is based upon?</li>
<li>If the term Jamstack grows insufficient as we consider more and more practices "best" outside of that immediate category, what terminology will we use to describe what we're doing?</li>
</ol>
<p>Here at TakeShape, we're putting our money where our mouth is and investing in the future tooling of the Jamstack. We're building out a concept called an API mesh: a tool to stitch together the inconsistent APIs and external services we use all the time in the Jamstack. That's one of the most common tasks we use serverless functions for, and it sure has never been a simple task. All those inconsistencies make merging the data from those disparate services quite a bear, but by offloading that difficulty to a third-party API mesh like TakeShape, you can get only the data you need from a single GraphQL endpoint. It's the key to modern Jamstack development and part of the answer to the four questions above.</p>
<p>We'd love to hear your thoughts on those four questions too! Make sure to tag us on Twitter at <a target="_blank" href="http://twitter.com/TakeShapeIO">@TakeShapeIO</a> and <a target="_blank" href="http://twitter.com/jadenguitarman">@jadenguitarman</a> with your thoughts and check out our site at <a target="_blank" href="http://takeshape.io">TakeShape.io</a> to learn more about our plans.</p>
]]></content:encoded></item><item><title><![CDATA[Our 8 favorite tools for monetizing your Jamstack website]]></title><description><![CDATA[The Jamstack and ecommerce are a lot like chocolate and avocado. At first, they don't sound like they'll go together, but they actually work really well; once you try it and realize the potential, you'll find that there's a whole community of people ...]]></description><link>https://hashnode.takeshape.io/our-8-favorite-tools-for-monetizing-your-jamstack-website</link><guid isPermaLink="true">https://hashnode.takeshape.io/our-8-favorite-tools-for-monetizing-your-jamstack-website</guid><category><![CDATA[ecommerce]]></category><category><![CDATA[APIs]]></category><category><![CDATA[api]]></category><dc:creator><![CDATA[Jaden Baptista]]></dc:creator><pubDate>Sat, 12 Jun 2021 01:54:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1623462633527/L01lN2BAJ.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The Jamstack and ecommerce are a lot like chocolate and avocado. At first, they don't sound like they'll go together, but they actually work really well; once you try it and realize the potential, you'll find that there's a whole community of people ready to share their amazing recipes on how to make them taste great together. In the same way, the Jamstack can sometimes appear incompatible with ecommerce, but it doesn't have to be! Here are our top ten favorite tools to help you start selling on your Jamstack site:</p>
<h2 id="takeshapehttptakeshapeio"><a target="_blank" href="http://takeshape.io">TakeShape</a></h2>
<p>TakeShape's API Mesh enables front-end developers to harness the power of the Jamstack by stitching together multiple external APIs with an intuitive internal CMS. I've actually been working on a series of livestreams about hydrating a product page with content from the TakeShape CMS and pricing data from Stripe, and while that might seem complex, TakeShape handles it smoothly. I just have to make one GraphQL request, and exactly the data I need arrives at the client, regardless of where that data originally came from. I wrote a summary article about those streams so you can see the process; you can check it out here.</p>
<p>I'm a little biased towards TakeShape, so I'll skip the ratings for this one, but I honestly love it; I'm including it in almost every project nowadays and think it's awesome.</p>
<h2 id="stripehttpstripecom"><a target="_blank" href="http://stripe.com">Stripe</a></h2>
<p>The whole point of ecommerce is to make money, so you need a tool to collect payment information and actually charge your customers. <strong>Stripe</strong> is the gold standard here. It's super simple to use, especially with the kits and libraries they provide, like <a target="_blank" href="https://stripe.com/docs/payments/checkout">Checkout</a> and <a target="_blank" href="https://stripe.com/docs/stripe-js">Elements</a>. Their documentation is best-in-class, and their developer support team is the most helpful I've ever had to deal with.</p>
<p>Some more complicated setups can start getting difficult to manage, as Stripe locks you to using their system of products, subscriptions, prices, and customers, but that system is more than adequate for the vast majority of use cases. You do have to use something on the server-side for this, since Stripe requires that you keep one of your API keys secret for obvious reasons. On the Jamstack, that means running it on a host that supports serverless functions or funneling the requests to Stripe through an API Mesh like <a target="_blank" href="http://takeshape.io">TakeShape</a>.</p>
<p>All in all, I give Stripe a <strong>9.5/10</strong> based on its incredible developer experience.</p>
<h2 id="snipcarthttpssnipcartcom"><a target="_blank" href="https://snipcart.com/">Snipcart</a></h2>
<p><strong>Snipcart</strong>'s tagline is <code>Add a shopping cart to any website</code>. It sure is bold, but they live up to that claim: devs from big names like <a target="_blank" href="https://www.fiverr.com/">Fiverr</a> to small ecom sites are turning to Snipcart to make selling on the Internet easier. Using just HTML and JavaScript, you can inject a cart onto your site, define some attributes to describe whatever you're selling, and hook up your "Add To Cart" button. <a target="_blank" href="https://docs.snipcart.com/v3/setup/installation">It's really that simple.</a> DX is definitely important, but if the product manager still needs a little more convincing, you can tell them that it's portable (it's not stuck to any specific stack) and will speed up your development by working with your existing site. A lot of the tools in this market require you to build the site to work with the tool, but Snipcart has no such requirements.</p>
<p>Snipcart is flexible enough to handle almost any use case well, but there are some situations where you might be better off reaching for a more low-level tool. For example, I was looking into building a marketplace, and the guys from Snipcart told me that having money moving from a buyer to a seller would be difficult to implement without the money first going through a single account, which opens you up to higher transaction fees and getting taxed on those transactions differently depending on your jurisdiction.</p>
<p>Snipcart isn't the magic solution to every ecommerce need, but it absolutely nails its intended functionality, so I can confidently give this a <strong>10/10</strong>.</p>
<h2 id="memberfulhttpsmemberfulcom"><a target="_blank" href="https://memberful.com/">Memberful</a></h2>
<p>Ecommerce is more than just paying for a product online; one of the core concepts in ecom is the membership subscription. <strong>Memberful</strong> aims to simplify and abstract away the difficulty of this often tricky payment model, and man, does it succeed. Take a look at <a target="_blank" href="https://memberful.com/help/how-to/create-a-plan/">this guide</a> for an example of its simplicity. It's definitely designed with non-developers in mind, so this will be a perfect fit for you if you're trying to paywall content on a larger site with dedicated content managers, if you're working on a site without a backend (like a Jamstack site), or with a Wordpress site (they've got an excellent and well-maintained plugin).</p>
<p>One thing I like about Memberful is that they're honest about their tool not being for everyone. <a target="_blank" href="https://memberful.com/alternatives/">In their own words</a>, "we'd rather recommend a competitor that’s a better fit for your business than try to hard sell you on Memberful." They go on to list some situations where Memberful might be a little tougher to use and then they offer some better alternatives. For example, Memberful works best on digital content, so if you're selling physical products via an online experience (like <a target="_blank" href="https://www.butcherbox.com/">Butcher Box</a> or <a target="_blank" href="https://www.dollarshaveclub.com/">Dollar Shave Club</a>), you might be better off with an all-in-one solution like <a target="_blank" href="https://squareup.com/us/en">Square</a>.</p>
<p>It's less flexible than other solutions, but Memberful takes the master-of-one over the jack-of-all-trades approach, so they make up for it by perfecting their core feature set. They've definitely earned my approval: <strong>9/10</strong>.  </p>
<h2 id="auth0httpauth0com"><a target="_blank" href="http://auth0.com">Auth0</a></h2>
<p>Authentication is really hard to get right, and no matter how many times I try to roll it myself, I always fail. But then I heard about <strong>Auth0</strong>, and I believe I physically sighed in relief. They just give you a login system with best practices built right in, something I was really bad at building previously. Their security experts have already worked out <a target="_blank" href="https://auth0.com/blog/how-retailers-can-prevent-ecommerce-fraud-this-holiday-season/">solutions to fraud and other problems</a> that modern ecommerce platforms are bound to face at some point or another.</p>
<p>That said, Auth0 can be difficult to get started with. It takes a bit of knowledge about those best practices to use Auth0's platform correctly without introducing more bugs and vulnerabilities. Thankfully, they've taken care of this by creating an excellent store of educational content on this topic to make integrating with them far easier. If you're interested in learning about how to work with Auth0, the best place to start is <a target="_blank" href="https://auth0.com/blog/">their blog</a>.</p>
<p>With that said, it's the most powerful solution to one of the most common problems on the Internet: authentication. Auth0 earns a <strong>8/10</strong> from me.</p>
<h2 id="foxyiohttpfoxyio-foxycart"><a target="_blank" href="http://foxy.io">Foxy.io</a> (FoxyCart)</h2>
<p>If Snipcart is the easy-to-use, build-into-your-existing-website shopping cart solution, <strong>Foxy.io</strong> is the super-powerful, only-for-devs, uber-customizable shopping cart solution. It's not better, just different from Snipcart, and so we use it in different scenarios. Perhaps when our small-town Mama's Pizza wants to start selling their pizzas online, Snipcart would be best, but Foxy.io might be the powerhouse needed to turn the gears behind BestBuy's website (large, but still with a single seller). Foxy.io doesn't manage inventory, while Snipcart does. Large sites like BestBuy likely are already handling that with a custom inventory solution, while something small like Mama's Pizza might make use of the inventory features of Snipcart to store their limited slate of pizza options. Foxy.io also can handle more payment gateways, which is unnecessary for smaller sites but could be critical for something as large as BestBuy.</p>
<p>I really like how they put it on <a target="_blank" href="https://wiki.foxycart.com/v/2.0/foxycarts_reason_for_being">this page</a>: "FoxyCart is not a turnkey solution. This generally makes FoxyCart perfect for some and just plain wrong for others." I couldn't have said it better; Foxy.io (what they call it now) does the cart and checkout really well, but if that's not the largest part and central focus of your website, then you might be better off with a simple solution like Snipcart.</p>
<p>It's perfect for a small set of ecommerce sites, but go with Snipcart for everything else. I give it a solid <strong>6/10</strong> though.</p>
<h2 id="sendgridhttpssendgridcom"><a target="_blank" href="https://sendgrid.com/">SendGrid</a></h2>
<p>Ah, <strong>SendGrid</strong>. Where were you all my life? Emailing is super difficult. The World Wide Web has evolved for the last 25 years, but the whole emailing system is stuck in 1996. SendGrid is kind of like a translator between that nonsense we had to deal with ages ago and the modern way we work with APIs. With customer outreach, support, and marketing being such a big part of the ecommerce world, tools that can make emailing easy like SendGrid have become absolutely indispensable. There's not that much to say about SendGrid other than the fact that they're trusted with handling crucial parts of the architecture of big websites like eBay, Nextdoor, Uber, AirBNB, and Yelp.</p>
<p>It does lean more towards being developer-friendly over content-creator-friendly, so you might find the interface a bit clunky if you're using SendGrid for blast emailing at a bigger company with dedicated marketers. It also looks like they funnel a lot of resources into development, which leaves customer support to focus on the biggest customers, so some smaller users have reported long stretches of time going by before hearing back from them.</p>
<p>Overall, I love SendGrid, and despite its minor flaws, it's always worked well for me. I give this one a <strong>9.5/10.</strong></p>
<h2 id="shopifyhttpswwwshopifycom"><a target="_blank" href="https://www.shopify.com/">Shopify</a></h2>
<p>You were expecting this one, weren't you? I'll admit, I used to rail against <strong>Shopify</strong>, and I still have my qualms, but I've come to see just how powerful it can be. It's probably the least technical tool on this list, so that immediately opens up all sorts of possibilities to non-developers. That's quite important to a lot of web development agencies as their developers then don't have to be bogged down with minor updates and can focus on future development, depending on how much you've customized the templates they give you. There's a massive community (as one would expect the largest ecommerce solution to garner), and they've created all sorts of plugins and templates to make the developer's job even easier.</p>
<p>There is a caveat in that last pro, though. The plugin system can put the stability of your website in the hands of others, and we've seen that go well — and occasionally very, very badly — for Wordpress. Using plugins like this can open you up to vulnerabilities exposed by the plugin authors (who can be sometimes slow to fix them), so make sure to only use plugins created by companies you trust. Shopify also tends to be more of a platform than an add-on tool, so while you get the convenience of using prebuilt templates, it's much harder to customize and add non-ecommerce content. Many ecommerce companies run blogs or other informational pages, which aren't so easy to implement (it's definitely possible though!). Lastly, there's the fees. On top of the fee to use Shopify (which can be anywhere from $9 - $2000 depending on your needs), you'll likely be paying a fee on every transaction (plus your payment processor's fee).</p>
<p>I've grown to enjoy Shopify recently, but for many it's an acquired taste. Given just how powerful it can be, I'll give it a <strong>7/10</strong>.</p>
<p>There you have it! That's my favorite 8 tools for turning a profit from your Jamstack site. It might've been historically difficult to combine ecommerce and the simplicity of the Jamstack, but thanks to tools like these 8, I'm hopeful that we'll be seeing more amazing ecommerce Jamstack experiences on the web in the future.</p>
<p>If you've got any questions about TakeShape or about the list in general, feel free to contact us on Twitter (<a target="_blank" href="http://twitter.com/takeshapeio">@TakeShapeIO</a>, <a target="_blank" href="http://twitter.com/jadenguitarman">@jadenguitarman</a>) or at <a target="_blank" href="http://takeshape.io">takeshape.io</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Using API Mesh to Streamline Ecommerce Development - A Stream Summary]]></title><description><![CDATA[Launching an ecommerce experience involves many different stakeholders. Developers, designers, product manager, content producers, marketers and merchandisers, each bring their own niche tools and workflows to the challenge to help  them do their job...]]></description><link>https://hashnode.takeshape.io/using-api-mesh-to-streamline-ecommerce-development-a-stream-summary</link><guid isPermaLink="true">https://hashnode.takeshape.io/using-api-mesh-to-streamline-ecommerce-development-a-stream-summary</guid><category><![CDATA[APIs]]></category><category><![CDATA[REST API]]></category><category><![CDATA[ecommerce]]></category><dc:creator><![CDATA[Jaden Baptista]]></dc:creator><pubDate>Mon, 24 May 2021 16:33:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1621873952020/7Yh7Qiq7G.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Launching an ecommerce experience involves many different stakeholders. Developers, designers, product manager, content producers, marketers and merchandisers, each bring their own niche tools and workflows to the challenge to help  them do their jobs better. For example, a marketer will usually prefer to use SendGrid over a custom internal emailing tool because it's more developed and easier to use. It's the same reason why product managers like using Github Issues, content producers like using a CMS, and merchandisers like using Shopify. It's up to developers to make all the different pieces fit into a single cohesive customer experience. This can be a real obstacle! Usually it requires backend development work and managing your own infrastructure, or at least it forces you to cobble some plugins together in WordPress or Shopify.</p>
<p>However, in the age of the Jamstack, <strong>there is a new way for front-end developers to solve this challenge. It's called an API Mesh.</strong></p>
<p><em>Term definition: an API Mesh is kind of like a <a target="_blank" href="https://en.wikipedia.org/wiki/Telephone_switchboard">switchboard</a> for APIs. You can set it up so that all the data and functionality you'd normally ping an API for (for example, from a CMS, or from Stripe, or from another other REST or GraphQL API) and pipe it into <a target="_blank" href="https://www.takeshape.io/">TakeShape</a> (the original API Mesh). Then with one GraphQL request to TakeShape, you can access whatever data or functionality you ask it for, regardless of its original source.</em></p>
<h2 id="the-plan">The Plan</h2>
<p>In a recent two-part stream over on my Twitch, I demonstrated the process of collecting data from multiple sources and using it to fill out a product page right on the client-side with TakeShape's API Mesh. The first part of the stream was mostly about planning, so here's what I came up with:</p>
<p>I decided that the majority of the data about the product itself should be stored in TakeShape's CMS (it's helpfully bundled in the same suite of tools as the API Mesh and a static site generator), while any data about pricing should be stored in Stripe. That last part might seem a bit strange to anyone who's used to working with traditional databases like MySQL: you'd think it would be better to have all the information about the product available from a single source, right?</p>
<p>Actually, it turns out that keeping all that product data in one place isn't necessary. Stripe makes for a good example here, since your pricing data is going to have to be stored there anyways if you're going to charge people using Stripe. If you have the price stored in your database (or CMS) along with all the other product data, then there will be some period of time — like when you're changing how much something costs — when it doesn't match exactly with the price you've got in Stripe. Then suddenly you've found yourself in a situation where you're advertising one price but charging the customer another.</p>
<p>To avoid scary situations like this, we need to keep Stripe as the single source of truth for any piece of data it reasonably should control. All of our prices and money-related data ought to be kept there and <strong>only</strong> there, while any other product attributes (like title, description, image, etc) could stay in the CMS.</p>
<h2 id="the-steps">The Steps</h2>
<ol>
<li><p><strong>Fill our data sources with data.</strong></p>
<p> This was actually the easy part, since I just borrowed one of <a target="_blank" href="https://github.com/takeshape/takeshape-samples">TakeShape's awesome starter kits on Github</a> (I used <a target="_blank" href="https://github.com/takeshape/takeshape-starter-shop">this</a> one). It came with everything I needed to get started, so I didn't have to do much setup. I actually ended up deleting 6 of the 9 products that came with the starter project, just for simplicity. After creating a new Stripe account, I created a <code>product</code> and a <code>price</code> in Stripe for each of the remaining sellable items, and called it done.</p>
</li>
<li><p><strong>Tell the API Mesh about all of our sources.</strong></p>
<p> The API Mesh needs to know where to collect data from if it's going to deliver it to us in one neat little packet, so we've got to give it our Stripe credentials and instructions on how to use their API. Now this might sound a bit complex, but it's really not; I went through this process live on the stream, and even with my impulsive rambling, it barely took 10 minutes.</p>
<p> All we really have to do is define these data sources as <code>service</code>s in TakeShape. They're listed under the Schema tab. Just click the "Connect Service" button to add a new one.</p>
<p> <img src="Connect Service Button" alt="https://images.takeshape.io/4d46e476-8704-42c4-8d0d-06ebdd0e3c93/dev/04691591-aa81-4b0b-bc43-31b4ed14ad10/screenshot1.png?auto=compress%2Cformat" /></p>
<p> To add a new service, click the Schema tab, and then the Connect Service button.</p>
<p> It'll walk you through a simple form just asking for the name of the service, the root endpoint (that's <code>[api.stripe.com](http://api.stripe.com)</code> in my case), and your auth details. Make sure to read the docs of the API you're using (<a target="_blank" href="https://stripe.com/docs/api/authentication?lang=curl">here</a> in my case) and the little note on the TakeShape form to make sure you're putting the right credentials in the right fields. In my initial stream, I made a tiny mistake here and used the wrong auth type. It wasn't a big deal; I just had to spend 5 minutes correcting it in the second stream.</p>
</li>
<li><p><strong>Tell the API Mesh to stitch data from those sources into one request.</strong></p>
<p> For this, we're going to jump into a little bit of JSON. Click the Export button on the Schema page to download the JSON that represents your entire project.</p>
<p> <img src="Export Schema" alt="https://images.takeshape.io/4d46e476-8704-42c4-8d0d-06ebdd0e3c93/dev/b646c274-af81-429f-bcf6-76a19beec944/export-button.png?auto=compress%2Cformat" /></p>
<p> Click the Export button on the Schema page to download JSON that represents your entire project.</p>
<p> The JSON it downloads might seem a bit unwieldy, but luckily most of it isn't relevant at the moment, so I use my code editor to fold a lot of it up so I can focus on what's important right now:</p>
<p> <img src="JSON Schema" alt="https://images.takeshape.io/4d46e476-8704-42c4-8d0d-06ebdd0e3c93/dev/884e93b6-3a5d-496d-a2cd-21bfe64115c0/schema.png?auto=compress%2Cformat" /></p>
<p> My folded-up, simple view of the JSON schema that represents my whole project</p>
<p> See the Stripe service we added earlier? The TakeShape GUI just edited this JSON file for us. For the queries, shapes, and forms, we're going to do essentially the same thing, except we're just going to edit the JSON file ourselves.</p>
<p> The first step for me was to go into the <code>Product</code> form and remove any property that mentions price data, since we're going to keep that in Stripe. If you're following along, make sure to check the <code>order</code> list too. Do the same thing in the <code>Product</code> shape, making sure to check the <code>required</code> list as well (that was another thing I briefly forgot about in the livestream, which I had to spend a minute or two correcting).</p>
<p> Next, we've got to add a property to the <code>Product</code> shape called <code>productId</code>, which would look something like this:</p>
<pre><code class="lang-json"> <span class="hljs-string">"productId"</span>: {
     <span class="hljs-attr">"type"</span>: <span class="hljs-string">"string"</span>,
     <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Product ID"</span>,
     <span class="hljs-attr">"minLength"</span>: <span class="hljs-number">1</span>
 }
</code></pre>
<p> That goes in the <code>properties</code> array under the <code>Product</code> shape.</p>
<p> The whole point of using this API Mesh in the first place was to help us developers stitch together all the tools our coworkers are using, so we've got to give whoever is in charge of maintaining the product entries the ability to enter the Stripe product ID into the CMS. TakeShape's CMS just displays <code>forms</code> to the user, which they can fill out to edit the product (or whatever other thing they're editing). So earlier, when we removed the price data from the <code>Product</code> form, we were removing the ability for our coworkers to add the price directly into TakeShape's CMS. Now that we want to let them add the Stripe product ID, we're going to add a new property to the <code>Product</code> form:</p>
<pre><code class="lang-json"> <span class="hljs-string">"productId"</span>: {
     <span class="hljs-attr">"widget"</span>: <span class="hljs-string">"singleLineText"</span>
 }
</code></pre>
<p> Now here comes the toughest part, though it's still fairly straightforward. We want TakeShape to automatically pull in price data from Stripe whenever we ask it about a product. In other words, we're asking TakeShape to <em>resolve</em> the product to its appropriate price data from Stripe. In line with that, let's give TakeShape a <em>resolver</em> so it knows what data to give us.</p>
<p> Go back to that <code>Product</code> shape and add this property:</p>
<pre><code class="lang-json"> <span class="hljs-string">"priceData"</span>: {
     <span class="hljs-attr">"type"</span>: <span class="hljs-string">"object"</span>,
     <span class="hljs-attr">"properties"</span>: {
         <span class="hljs-attr">"inCents"</span>: {
             <span class="hljs-attr">"type"</span>: <span class="hljs-string">"number"</span>
         }
     },
     <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Price Data"</span>,
     <span class="hljs-attr">"@resolver"</span>: {
         <span class="hljs-attr">"name"</span>: <span class="hljs-string">"rest:get"</span>,
         <span class="hljs-attr">"service"</span>: <span class="hljs-string">"stripe"</span>,
         <span class="hljs-attr">"options"</span>: {
              <span class="hljs-attr">"fieldName"</span>: <span class="hljs-string">"priceData"</span>,
             <span class="hljs-attr">"path"</span>: <span class="hljs-string">"v1/prices"</span>
         },
         <span class="hljs-attr">"argsMapping"</span>: {
             <span class="hljs-attr">"searchParams.product"</span>: [
                 [
                     <span class="hljs-string">"jsonPath"</span>,
                     {
                         <span class="hljs-attr">"path"</span>: <span class="hljs-string">"$.source.productId"</span>
                     }
                 ]
             ]
         },
         <span class="hljs-attr">"resultsMapping"</span>: {
             <span class="hljs-attr">"inCents"</span>: [
                 [
                     <span class="hljs-string">"jsonPath"</span>,
                     {
                         <span class="hljs-attr">"path"</span>: <span class="hljs-string">"steps[0].data[0].unit_amount"</span>
                     }
                 ]
             ]
         }
     }
 }
</code></pre>
<p> Here's a little breakdown for the curious:</p>
<ol>
<li>First, we define that this is going to be an object, and that it'll have one property of its own called <code>inCents</code>, which will be a number.</li>
<li>Then, we tell it to get information from a GET request to the <code>stripe</code> service we defined earlier, at the <code>/v1/prices</code> endpoint.</li>
<li>Then, the API mesh is instructed to send the <code>productID</code> of this particular product into Stripe as a search parameter.</li>
<li><p>Lastly, we're asking that the <code>unit_amount</code> buried in Stripe's response be piped into that <code>inCents</code> property we defined earlier, so that our end result ends up nice and tidy.</p>
<p>We're done with this file, so just <a target="_blank" href="https://www.takeshape.io/docs/exporting-and-importing-the-schema/">reimport that JSON file back into TakeShape</a> and let the API Mesh do its thing.</p>
</li>
</ol>
</li>
<li><p><strong>Fill our product page with data from the API Mesh.</strong></p>
<p> If we're going to hydrate our product page on the client, then we need to first request the data from our API Mesh. The GraphQL query we're sending to TakeShape would look something like this:</p>
<pre><code class="lang-jsx"> <span class="hljs-keyword">const</span> query = <span class="hljs-string">`{
     getProductList {
         items {
             description
                 image {
                     sourceUrl
                 }
                 name
                 priceData {
                     inCents
                 }
                 category {
                     searchSummary
                 }
                 soldOut
             }
         }
     }`</span>;
</code></pre>
<p> Here's the function I wrote to actually send that request:</p>
<pre><code class="lang-jsx"> <span class="hljs-keyword">const</span> getMeMyData = <span class="hljs-keyword">async</span> index =&gt; {
     <span class="hljs-keyword">let</span> req = <span class="hljs-keyword">await</span> fetch(
         <span class="hljs-string">`https://api.takeshape.io/project/<span class="hljs-subst">${TS_PRODUCT_ID}</span>/v3/graphql`</span>, 
         {
             <span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
             <span class="hljs-attr">headers</span>: {
                 <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>,
                 <span class="hljs-string">'Authorization'</span>: <span class="hljs-string">`Bearer <span class="hljs-subst">${TS_API_KEY}</span>`</span>
             },
             <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({ query })
         }
     );

     <span class="hljs-keyword">let</span> result = <span class="hljs-keyword">await</span> req.json();
     <span class="hljs-keyword">return</span> result.data.getProductList.items[index];
 };
</code></pre>
<p> And then here's the function that uses that data to hydrate my HTML:</p>
<pre><code class="lang-jsx"> <span class="hljs-keyword">const</span> hydrateMePage = <span class="hljs-keyword">async</span> productIndex =&gt; {
     <span class="hljs-keyword">const</span> product_data = <span class="hljs-keyword">await</span> getMeMyData(productIndex);

     <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"product-title"</span>).innerText = product_data.name;
     <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"product-description"</span>).innerText = product_data.description;

     <span class="hljs-keyword">let</span> productImage = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"product-image"</span>);
     productImage.src = product_data.image.sourceUrl;
     productImage.alt = product_data.name;

     <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".product-price &gt; span"</span>).innerText = <span class="hljs-string">"$"</span> + (product_data.priceData.inCents / <span class="hljs-number">100</span>).toFixed(<span class="hljs-number">2</span>);
     <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"product-category"</span>).innerText = product_data.category.searchSummary;
     <span class="hljs-keyword">if</span> (product_data.soldOut) <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"main.container"</span>).classList.add(<span class="hljs-string">"sold-out"</span>);
 };
</code></pre>
<p> Those two small functions set us up to fill out our whole page with data from multiple sources without practically any technical debt. Just run a <code>hydrateMePage(0)</code> and it'll fill the page with data like magic; except that it's not magic, it's an API Mesh stitching together our CMS and Stripe data so we don't have to do the legwork of stitching it ourselves.</p>
</li>
</ol>
<h2 id="the-results">The Results</h2>
<p>And with those four steps, we've suddenly created an <em>entire data pipeline</em> for our ecommerce website. To create a search results page, or a homepage, or anything else, we don't even have to replicate all the steps; depending on whether you need to add more sources or not, you'd just start from step 2 or 4.</p>
<p>If you're interested in seeing more builds like this, I stream over on <a target="_blank" href="http://twitch.tv/jadenbaptista">my Twitch</a> every Monday afternoon. We also talk with leaders in the web development community about their experiences with interactive interviews there on Thursday afternoons. Make sure to follow <a target="_blank" href="http://twitter.com/takeshapeio">@takeshapeio</a> and <a target="_blank" href="http://twitter.com/jadenguitarman">@jadenguitarman</a> on Twitter to get the latest updates.</p>
]]></content:encoded></item><item><title><![CDATA[How to set up VSCode to work with TakeShape's Metaschema]]></title><description><![CDATA[Nobody likes typos in JSON. Let's make VSCode catch them for us when writing a TakeShape schema.
When writing JSON it's easy to fudge the syntax a bit, usually by missing a quote or a colon. Thankfully, coding tools like VSCode are good at catching t...]]></description><link>https://hashnode.takeshape.io/how-to-set-up-vscode-to-work-with-takeshapes-metaschema</link><guid isPermaLink="true">https://hashnode.takeshape.io/how-to-set-up-vscode-to-work-with-takeshapes-metaschema</guid><category><![CDATA[GraphQL]]></category><category><![CDATA[Visual Studio Code]]></category><category><![CDATA[json]]></category><dc:creator><![CDATA[Jaden Baptista]]></dc:creator><pubDate>Wed, 12 May 2021 22:46:50 GMT</pubDate><content:encoded><![CDATA[<p>Nobody likes typos in JSON. Let's make VSCode catch them for us when writing a TakeShape schema.</p>
<p>When writing JSON it's easy to fudge the syntax a bit, usually by missing a quote or a colon. Thankfully, coding tools like VSCode are good at catching these errors. However, a far sneakier problem to identify is when the format of the keys and values in a JSON file don't abide by the internal rules of a program that relies on the JSON you are writing. This can be easily solved by using a JSON metaschema to automatically validate JSON, which will give VSCode the power to warn you when your  JSON doesn't match what TakeShape is expecting to be in a <code>schema.json</code>. </p>
<p><em>Term definition:</em> TakeShape's metaschema is a JSON schema that VSCode can use to regulate TakeShape's <code>schema.json</code> files. It's a schema for a schema; hence, a "metaschema". TakeShape's metaschema can be found at <a target="_blank" href="https://schema.takeshape.io/project-schema">https://schema.takeshape.io/project-schema</a></p>
<h2 id="setting-up-vscode-to-use-takeshapes-metaschema"><strong>Setting up VSCode to use TakeShape's metaschema</strong></h2>
<ol>
<li><p><strong>In VSCode, go to your Preferences and find the settings.json file.</strong></p>
<p> It's under the Settings button in the bottom left corner, under the Settings tab. You can also get there with the <code>Cmd</code> + <code>,</code> shortcut (<code>Ctrl</code> + <code>,</code> on Windows).</p>
<p> Search for <code>json</code> and click on the link that says <code>Edit in settings.json</code>.</p>
</li>
<li><p><strong>Tell VSCode to use the TakeShape metaschema.</strong></p>
<p> Add the following to the <code>json.schemas</code> array:</p>
<pre><code class="lang-json"> {
     <span class="hljs-attr">"fileMatch"</span>: [
         <span class="hljs-string">"schema*json"</span>
     ],
     <span class="hljs-attr">"url"</span>: <span class="hljs-string">"https://schema.takeshape.io/project-schema"</span>
 }
</code></pre>
<p> In short, this tells VSCode to use the TakeShape metaschema on every file that matches <code>schema*json</code>, including — but not limited to — <code>schema.json</code>, <code>schema.v2.jneiubciub.json</code>, and <code>schema.v4.json</code>. </p>
</li>
<li><p><strong>Test to make sure it works.</strong></p>
<p> If you have a <code>schema.json</code> file handy, feel free to use that; otherwise, you can download one from any of the repos listed at <a target="_blank" href="https://github.com/takeshape/patterns">https://github.com/takeshape/patterns</a>. </p>
<p> You should see something like this, where you'll get a yellow squiggly warning line if you try to add a property to the schema that TakeShape won't know what to do with.</p>
<p> <img src="https://images.takeshape.io/4d46e476-8704-42c4-8d0d-06ebdd0e3c93/dev/5eb74ef0-36e5-4c57-90d8-8e67f3023264/metaschema%20demo.png?auto=compress%2Cformat" alt="Demo" /></p>
</li>
</ol>
<p>Now VSCode will optimize your workflow by reminding you of any typos in your <code>schema.json</code> right as you type them, instead of when you import the whole schema back into TakeShape later. If you have any trouble with this process, feel free to reach out to the TakeShape team by clicking the chat bubble in the bottom right corner of your screen.</p>
]]></content:encoded></item></channel></rss>