{"componentChunkName":"component---src-templates-author-jsx","path":"/blog/author/shahidh_k_muhammed_hasura/","result":{"data":{"prismic":{"allFeaturedblogs":{"edges":[{"node":{"featured_blogs_enabled":true,"heading":[{"type":"paragraph","text":"Featured posts","spans":[]}],"featured_blog_1":{"__typename":"PRISMIC_Blog","_linkType":"Link.document","blog_header_image":{"dimensions":{"width":790,"height":395},"alt":null,"copyright":null,"url":"https://images.prismic.io/www-static/6d8d81b1-971a-4313-b033-b4e125cb14a0_MondoDB-blog-header-790x395.PNG?auto=compress,format"},"blog_headline":[{"type":"heading1","text":"Introducing DigitalOcean Managed MongoDB – a fully managed, database as a service for modern apps","spans":[]}],"blog_post_date":"2021-06-29","blog_post_content":[{"type":"paragraph","text":"MongoDB is one of the most popular databases, and it’s ideal for apps that evolve rapidly and need to handle huge volumes of data and traffic. It offers advantages like flexible document schemas, code-native data access, change-friendly design, and easy horizontal scale-out.","spans":[{"start":22,"end":44,"type":"hyperlink","data":{"link_type":"Web","url":"https://db-engines.com/en/ranking","target":"_blank"}}]},{"type":"paragraph","text":"However, building and maintaining MongoDB clusters from the ground up can be a huge undertaking. Developers often complain that they have to spend their valuable time and resources on database management. Well, we’ve been listening and have some great news: accessing and managing MongoDB on DigitalOcean just got a lot simpler!","spans":[]},{"type":"paragraph","text":"We are excited to announce that DigitalOcean Managed MongoDB is now in General Availability. Managed MongoDB is a fully managed, database as a service (DBaaS) offering from DigitalOcean, built in partnership with and certified by MongoDB Inc. It provides you all the technical capabilities that make MongoDB so beloved in the developer community. Together we have ensured that you will get access to all the latest releases of the MongoDB document database as they become available.","spans":[{"start":32,"end":91,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.digitalocean.com/products/managed-databases-mongodb/"}},{"start":230,"end":241,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.mongodb.com/","target":"_blank"}}]},{"type":"paragraph","text":"Managed MongoDB simplifies the MongoDB administration. Developers of all skill levels, even those who do not have prior experience in databases, can spin up MongoDB clusters in just a few minutes. We handle the provisioning, managing, scaling, updates, backups, and security of your MongoDB clusters, allowing you to offload the complex, time consuming –yet critical – database administration tasks to us. This empowers you to focus on what really matters: building awesome apps.","spans":[]},{"type":"embed","oembed":{"height":113,"width":200,"embed_url":"https://www.youtube.com/watch?v=NvHQSV7jnKA","type":"video","version":"1.0","title":"Create a MongoDB Database on DigitalOcean","author_name":"DigitalOcean","author_url":"https://www.youtube.com/c/Digitalocean","provider_name":"YouTube","provider_url":"https://www.youtube.com/","cache_age":null,"thumbnail_url":"https://i.ytimg.com/vi/NvHQSV7jnKA/hqdefault.jpg","thumbnail_width":480,"thumbnail_height":360,"html":"<iframe width=\"200\" height=\"113\" src=\"https://www.youtube.com/embed/NvHQSV7jnKA?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>"}},{"type":"heading2","text":"Benefits of Managed MongoDB","spans":[]},{"type":"paragraph","text":"","spans":[]},{"type":"list-item","text":"Easy set up and maintenance: We create the database clusters for you. Simply choose the cluster configuration (e.g., memory, disk size, number of nodes, etc.), and the data center in which you want to host the database. Follow a few simple steps and your database cluster will be up and running in a matter of minutes. You can spin up clusters using the cloud control panel, CLI, or API.\n\n","spans":[{"start":0,"end":28,"type":"strong"}]},{"type":"list-item","text":"Automatic daily backups with point in time recovery: Data is one of the most important assets of an app, so it’s critical to backup your database. We take backups of your entire clusters automatically on a daily basis, for free. We also provide a point in time recovery for 7 days, that way if things go wrong due to human error, machine error, or some combination of both, you can easily restore the database as it was at any point in the previous 7 days. \n\n","spans":[{"start":0,"end":52,"type":"strong"}]},{"type":"list-item","text":"Automatic updates and access to latest MongoDB releases: You get access to MongoDB 4.4. This is the latest release of MongoDB and comes packed with numerous enhancements like hedged reads, rust, and swift drivers. Since we have developed Managed MongoDB in partnership with MongoDB Inc, you will always get access to new releases as they become available. With Managed MongoDB, the updates happen automatically. Just select a date and time for the updates and we take care of the rest. This makes it easy to stay up to date with MongoDB releases without disrupting your business.\n\n","spans":[{"start":0,"end":56,"type":"strong"},{"start":148,"end":169,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.mongodb.com/new","target":"_blank"}}]},{"type":"list-item","text":"High availability with automated failover: If your database goes down, it can take down the entire app, leading to bad customer experiences. With Managed MongoDB, you can easily minimize the downtime for your database and make it highly available with standby nodes. Standby nodes add redundancy, so if for example the primary node fails, the standby node is immediately promoted to primary and begins serving requests while we provision a replacement standby node in the background.\n\n","spans":[{"start":0,"end":42,"type":"strong"}]},{"type":"list-item","text":"Scale up easily to handle traffic spikes: As your app gains traction and the usage grows, it’s important to have a database that can keep up with the increased demand. With Managed MongoDB, you can easily scale up the size of database nodes when needed.\n\n","spans":[{"start":0,"end":41,"type":"strong"}]},{"type":"list-item","text":"Secure by default: Since data is critical, it also needs to be secure. We encrypt data at rest with LUKS and in transit with SSL. When you create a new cluster, it’s placed in a VPC network by default that provides a more secure connection between resources. You can also restrict access to your nodes to prevent brute-force password and denial-of-service attacks.","spans":[{"start":0,"end":18,"type":"strong"},{"start":178,"end":189,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.digitalocean.com/docs/networking/vpc/"}}]},{"type":"heading2","text":"The need for Managed Databases","spans":[]},{"type":"paragraph","text":"DigitalOcean’s mission is to simplify cloud computing so developers, startups, and SMBs can spend more time building software that changes the world. While databases are a critical component to any application, building, maintaining, and scaling them can be complex and time consuming. For developers that are building apps for their business, database administration is often not a core focus area. But it’s quite common to find developers that write the code and then also roll up their sleeves to maintain databases. Such users would rather offload the tedious database administration and focus their limited time and energy on building and enhancing their apps. ","spans":[]},{"type":"paragraph","text":"With this in mind, we introduced Managed Databases a couple of years ago and are excited to add Managed MongoDB to our portfolio. With this release, DigitalOcean Managed Databases now supports the following engines:","spans":[{"start":33,"end":50,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.digitalocean.com/products/managed-databases/"}}]},{"type":"image","url":"https://images.prismic.io/www-static/87745cc1-1c5f-4463-b104-104b7fc30dc7_managed-databases-logos.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":849,"height":104}},{"type":"paragraph","text":"Managed MongoDB launch comes on the heels of DigitalOcean App Platform, a modern, reimagined PaaS (Platform as a Service) that we released a few months ago. App Platform makes it very easy to build, deploy, and scale apps and static sites. You can deploy code by simply pointing to your GitHub and GitLab repos, and App Platform will do all the heavy lifting of managing infrastructure, app runtimes, and dependencies. App Platform, along with Managed Databases, helps fulfill DigitalOcean’s mission by empowering developers, startups, and SMBs to focus more on their apps, and less on the underlying infrastructure and databases.","spans":[{"start":45,"end":70,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.digitalocean.com/products/app-platform/"}}]},{"type":"heading2","text":"How Managed MongoDB works","spans":[]},{"type":"paragraph","text":"DigitalOcean provides you with various compute options to build your apps like:","spans":[]},{"type":"list-item","text":"Droplets: On-demand, Linux virtual machines suitable for production business applications and personal passion projects.","spans":[{"start":0,"end":8,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.digitalocean.com/products/droplets/"}}]},{"type":"list-item","text":"DigitalOcean Kubernetes: Managed Kubernetes with automatic scaling, upgrades, and a free control plane.","spans":[{"start":0,"end":23,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.digitalocean.com/products/kubernetes/"}}]},{"type":"list-item","text":"DigitalOcean App Platform: A fully managed Platform as a Service.","spans":[{"start":0,"end":25,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.digitalocean.com/products/app-platform/"}}]},{"type":"paragraph","text":"No matter which compute option you choose to build your apps, you can easily add Managed MongoDB to it. In addition to this, Managed MongoDB also integrates with the Node.js 1-Click App from DigitalOcean Marketplace making it a lot easier to build Node.js apps.","spans":[{"start":166,"end":215,"type":"hyperlink","data":{"link_type":"Web","url":"https://marketplace.digitalocean.com/apps/nodejs"}}]},{"type":"heading2","text":"Simple, predictable pricing","spans":[]},{"type":"paragraph","text":"Just like all DigitalOcean products, Managed MongoDB provides simple, predictable pricing that allows you to control costs and prevent any surprise bills. You can spin up a database cluster for just $15/month, or a highly available three-node replica set for $45/month. Click here for more information.","spans":[{"start":270,"end":301,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.digitalocean.com/pricing/#managed-databases"}}]},{"type":"heading2","text":"Regional availability","spans":[]},{"type":"paragraph","text":"Managed MongoDB is currently available in the following regions:","spans":[]},{"type":"list-item","text":"NYC3 (New York, USA)","spans":[]},{"type":"list-item","text":"FRA1 (Frankfurt, Germany)","spans":[]},{"type":"list-item","text":"AMS3 (Amsterdam, Netherlands)","spans":[]},{"type":"paragraph","text":"We will be making Managed Mongo available in other regions soon. Please check out the release notes for most up to date information on regional availability.","spans":[{"start":86,"end":99,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.digitalocean.com/docs/release-notes/"}}]},{"type":"heading2","text":"Join us at deploy, DigitalOcean’s virtual user conference","spans":[]},{"type":"paragraph","text":"Today we have deploy, DigitalOcean’s signature user conference, which focuses on celebrating, educating, and connecting awesome builders from all over the world.","spans":[{"start":14,"end":20,"type":"hyperlink","data":{"link_type":"Web","url":"https://deploy.digitalocean.com/home"}}]},{"type":"paragraph","text":"Check out the keynote session from DigitalOcean's CEO, Yancey Spruill, in which he talks about where we're headed as a company and shares some exciting product updates. His keynote will be followed by sessions from community members, engineers, customers, and other experts that are building technologies and businesses powered by the cloud. With live Q&A and an active Discord server, there’s ample opportunity to engage and learn something new. Click here to attend the deploy conference.","spans":[{"start":14,"end":69,"type":"hyperlink","data":{"link_type":"Web","url":"https://deploy.digitalocean.com/agenda/session/552806"}},{"start":347,"end":384,"type":"hyperlink","data":{"link_type":"Web","url":"http://do.co/deploy-discord"}},{"start":461,"end":489,"type":"hyperlink","data":{"link_type":"Web","url":"http://do.co/deploy"}}]},{"type":"paragraph","text":"We are also launching a hackathon for DigitalOcean Managed MongoDB. Learn how you can participate, submit an app and get a t-shirt.","spans":[{"start":24,"end":66,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.digitalocean.com/mongodb-hackathon"}}]},{"type":"paragraph","text":"We hope you will give Managed MongoDB a try. Here are some sample datasets and sample apps that you can use to kick the tires. Check out the docs and let us know what you think!","spans":[{"start":22,"end":43,"type":"hyperlink","data":{"link_type":"Web","url":"https://cloud.digitalocean.com/databases/new?engine=mongodb"}},{"start":59,"end":90,"type":"hyperlink","data":{"link_type":"Web","url":"https://github.com/do-community/mongodb-resources","target":"_blank"}},{"start":141,"end":145,"type":"hyperlink","data":{"link_type":"Web","url":"https://docs.digitalocean.com/products/databases/mongodb/"}}]},{"type":"paragraph","text":"If you’d like to have a conversation about using DigitalOcean and Managed MongoDB in your business, please feel free to contact our sales team.","spans":[{"start":120,"end":142,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.digitalocean.com/company/contact/sales/"}}]},{"type":"paragraph","text":"Happy coding!","spans":[]},{"type":"paragraph","text":"André Bearfield","spans":[]},{"type":"paragraph","text":"Director of Product Management","spans":[]}],"tags":[{"tag1":{"__typename":"PRISMIC_Tag","tag":"Product Updates","_linkType":"Link.document","_meta":{"uid":"product-updates"}}}],"author":{"__typename":"PRISMIC_Author","author_name":"André Bearfield","author_image":{"dimensions":{"width":553,"height":547},"alt":"André Bearfield","copyright":null,"url":"https://images.prismic.io/www-static/fdc7c85186f0a850b04083e1d4306bd1c19772e8_andre-bearfield.png?auto=compress,format"},"_meta":{"uid":"andre-bearfield"}},"_meta":{"uid":"introducing-digitalocean-managed-mongodb"}},"featured_blog_2":{"__typename":"PRISMIC_Blog","_linkType":"Link.document","blog_header_image":{"dimensions":{"width":790,"height":400},"alt":"Droplet Console","copyright":null,"url":"https://images.prismic.io/www-static/710499ae-78cc-4179-afc1-15793637b200_DODX3727-790x400-logo-2.jpg?auto=compress,format"},"blog_headline":[{"type":"heading1","text":"Securely connect to Droplets with SSH key pairs using a new Droplet Console","spans":[]}],"blog_post_date":"2021-08-10","blog_post_content":[{"type":"paragraph","text":"The famous author Ken Blanchard once said, “Feedback is the breakfast of champions.\" This is something we truly believe at DigitalOcean, and we always strive to enhance our products based on customer feedback.","spans":[]},{"type":"paragraph","text":"With this goal in mind, we are excited to introduce a new Droplet Console that will make it much easier to connect to your Droplets securely. The new Droplet Console provides one-click SSH access to your Droplets through a native-like SSH/Terminal experience. It also eliminates the need for a password or manual configuration of SSH keys. Starting today, we’re pleased to announce that the new Droplet Console is now available to all Droplet users.","spans":[]},{"type":"heading2","text":"Why you should be using Secure Shell (SSH) ","spans":[]},{"type":"paragraph","text":"Password-based security is notoriously insecure due to password fatigue and the overuse of passwords such as ‘123456’. Secure Shell or SSH is a network communication protocol that solves this by using passwordless solutions for encryption, enabling two computers to communicate and securely share data. At a high level, SSH works by creating cryptographic key pairs consisting of a public and private key, which are computer generated and stored separately to ensure their security. ","spans":[{"start":80,"end":117,"type":"hyperlink","data":{"link_type":"Web","url":"https://cybernews.com/best-password-managers/most-common-passwords/"}}]},{"type":"paragraph","text":"SSH has become the default encryption protocol for many industries, but it was difficult to use SSH keys with DigitalOcean’s current Recovery (VNC) console, which is why we developed our new Droplet Console. The new Droplet Console is backed by an agent that security supervises the key pair, while also providing one-click SSH access to our users. You can see the full list of features below.","spans":[]},{"type":"heading2","text":"The new Droplet Console: More time saving, less time wasting ","spans":[]},{"type":"paragraph","text":"The new Droplet Console is for everyone who is looking to build fast, secure apps and avoid hassles with SSH access & usability issues.","spans":[]},{"type":"paragraph","text":"In addition to easier SSH access, the new Droplet Console comes with:","spans":[]},{"type":"list-item","text":"Copy/paste text: Instead of typing lengthy key pairs and text manually, you can use copy/paste to save time. ","spans":[{"start":0,"end":17,"type":"strong"}]},{"type":"list-item","text":"Multi-color support: Multi-color support makes the console more useful and intuitive, and breaks the conventional standard appearance which is black text on a white background. ","spans":[{"start":0,"end":41,"type":"strong"}]},{"type":"list-item","text":"Multi-language support: DigitalOcean’s new Droplet Console supports multiple languages, meaning you can now type and view any content in any language that is supported by UTF-8","spans":[{"start":0,"end":24,"type":"strong"}]},{"type":"list-item","text":"OS/images supported: Linux distributions (Ubuntu(16.04 - 20.04), Fedora (32 & 33), Debian (9), CentOS (7.6 & 8.3), CentOS 8 Stream, Rocky Linux and Marketplace images.","spans":[{"start":0,"end":20,"type":"strong"},{"start":148,"end":159,"type":"hyperlink","data":{"link_type":"Web","url":"https://marketplace.digitalocean.com/"}}]},{"type":"paragraph","text":"The new Droplet Console is available by default on any new Droplets you spin up. You can also enable it manually on older Droplets. Click here to learn more!","spans":[{"start":132,"end":157,"type":"hyperlink","data":{"link_type":"Web","url":"https://docs.digitalocean.com/products/droplets/how-to/connect-with-console/"}}]},{"type":"paragraph","text":"Check out this short walkthrough video that shows the new Droplet Console in action: ","spans":[]},{"type":"embed","oembed":{"type":"video","embed_url":"https://www.youtube.com/watch?v=Qt7QihVuxiE","title":"Access Your Droplet Terminal Through the Web Console","provider_name":"YouTube","thumbnail_url":"https://i.ytimg.com/vi/Qt7QihVuxiE/hqdefault.jpg","provider_url":"https://www.youtube.com/","author_name":"DigitalOcean","author_url":"https://www.youtube.com/c/Digitalocean","height":113,"width":200,"version":"1.0","thumbnail_height":360,"thumbnail_width":480,"html":"<iframe width=\"200\" height=\"113\" src=\"https://www.youtube.com/embed/Qt7QihVuxiE?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>"}},{"type":"paragraph","text":"We hope you’re excited about the new Droplet Console. You’re welcome to spin some Droplets up right now, and try out the new Droplet Console – why wait?","spans":[{"start":72,"end":103,"type":"hyperlink","data":{"link_type":"Web","url":"https://cloud.digitalocean.com/droplets/new"}}]},{"type":"paragraph","text":"Happy coding!","spans":[]},{"type":"paragraph","text":"Harsh Banwait, Senior Product Manager","spans":[]}],"tags":[{"tag1":{"__typename":"PRISMIC_Tag","tag":"Product Updates","_linkType":"Link.document","_meta":{"uid":"product-updates"}}}],"author":{"__typename":"PRISMIC_Author","author_name":"Harsh Banwait","author_image":{"dimensions":{"width":600,"height":399},"alt":null,"copyright":null,"url":"https://images.prismic.io/www-static/e83ff690-b20c-4d88-a2b6-57e562558cd6_download.png?auto=compress,format"},"_meta":{"uid":"harsh-banwait"}},"_meta":{"uid":"new-droplet-console-ssh-support"}},"featured_blog_3":{"__typename":"PRISMIC_Blog","_linkType":"Link.document","blog_header_image":{"dimensions":{"width":790,"height":400},"alt":null,"copyright":null,"url":"https://images.prismic.io/www-static/588e28d3-d41e-480b-937b-8c3b19201f6e_DODX3568-790x400-Blog.jpg?auto=compress,format"},"blog_headline":[{"type":"heading1","text":"How to scale your SaaS product without breaking the bank","spans":[]}],"blog_post_date":"2021-06-22","blog_post_content":[{"type":"paragraph","text":"These days, if you are in the business of software, chances are you are delivering or plan to deliver your services using a Software-as-a-Service (SaaS) model. A combination of internet-based delivery, subscription-based pricing, and low-friction product experiences have made SaaS solutions valuable tools for their users, and an excellent vehicle for software builders looking to distribute their products.","spans":[]},{"type":"paragraph","text":"These factors have made SaaS solutions ubiquitous; SaaS is the largest segment in the public cloud market, and is used to provide functionality ranging from personal finance apps for consumers, to productivity software for businesses, and even tools and services for software developers themselves to compose their applications and simplify their workflows. It is also not uncommon to find micro-SaaS applications being built for specific industries such as retail, job functions such as accounting or marketing, or tasks such as event management. ","spans":[]},{"type":"paragraph","text":"The best thing about this SaaS wave has been that it has allowed a new generation of software builders to build and monetize applications and participate in the digital economy. Previously, you had to be a big company with lots of resources, name recognition and distribution networks to successfully sell software products. Now, irrespective of whether you are a single person working on a passion project, a small team of developers in a startup, or a small and medium-sized business (SMB), the SaaS model enables you to express your ideas in the form of software and deliver them to customers anywhere in the world.","spans":[]},{"type":"heading2","text":"The unique challenges of building SaaS solutions","spans":[]},{"type":"paragraph","text":"","spans":[]},{"type":"paragraph","text":"Despite the opportunities that come with the widespread adoption of SaaS products, software builders still have to answer key questions in their journey to building successful SaaS products. Understanding what customers to target, features to prioritize, how to price your product, and how to acquire customers are all critical questions to figure out while you are also doing the important job of actually building and operating the product. ","spans":[]},{"type":"paragraph","text":"Writing the code, testing, deployment, monitoring the usage in production, and ensuring that your apps are able to handle the additional demand when customer base and usage grows are all essential and time-consuming tasks.","spans":[]},{"type":"paragraph","text":"Additionally, being able to test multiple ideas, pivot, and double down on the ideas that actually work is critical in early stages of SaaS development. Once growth comes, it is equally important to scale up without compromising on performance or reliability. Needless to say, all of this needs to be economically viable as well, since not everyone has the resources of large SaaS providers like Salesforce or Adobe.","spans":[]},{"type":"heading2","text":"Cloud Computing enables builders but also poses challenges","spans":[]},{"type":"paragraph","text":"","spans":[]},{"type":"paragraph","text":"Fortunately, for the act of building and operating your apps, cloud computing can help take some load off your shoulders. Unless you have the scale and resources of Facebook, chances are you are not going to set up your own data centers to host the computing infrastructure that powers your SaaS company. Public cloud infrastructure providers can bring great value to SaaS builders by providing on-demand computing services with usage-based pricing. However, just like how the legacy software companies weren't built for the SaaS model, the early (and big) cloud computing services were not optimized for the unique needs of small SaaS building teams. ","spans":[]},{"type":"paragraph","text":"Smaller SaaS teams face challenges with large cloud computing providers, including:","spans":[]},{"type":"heading4","text":"Too many technology options","spans":[]},{"type":"paragraph","text":"There are just too many options for tech stacks on which to build your SaaS - programming languages, application development frameworks, libraries, runtime environments, architectural patterns, and deployment models - and the list is growing by the day.","spans":[]},{"type":"heading4","text":"Complexity of cloud computing services","spans":[]},{"type":"paragraph","text":"Even when you have decided on a technology stack, there is a lot of cloud vendor-specific terminology you need to learn and heavy lifting you need to do to build on the cloud, not all of which contributes to making your SaaS applications successful.","spans":[]},{"type":"heading4","text":"Unpredictable costs","spans":[]},{"type":"paragraph","text":"The experimentation necessary in early stages of SaaS development, as well as the scaling of applications required during the growth phase, call for affordable and predictable pricing from your cloud provider. The last thing SaaS teams want is surprising and indecipherable bills from your cloud provider. Unfortunately, smaller businesses often experience unpredictable costs with cloud providers who are busy serving only the large enterprises.","spans":[]},{"type":"heading2","text":"DigitalOcean provides a simple, cost effective solution for SaaS builders","spans":[]},{"type":"paragraph","text":"Fortunately, at DigitalOcean we have a laser focus on small software development teams, who are trying to build the next generation of applications. Today, DigitalOcean customers are already building SaaS applications which serve all kinds of customers.","spans":[{"start":191,"end":217,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.digitalocean.com/solutions/saas/"}}]},{"type":"paragraph","text":"We believe SaaS builders should focus on building apps that power their business, and not spend their valuable time on managing infrastructure. That is exactly what we have been able to enable through our intuitive products that are built for scale and reliability.","spans":[{"start":205,"end":223,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.digitalocean.com/products/"}}]},{"type":"list-item","text":"Vidazoo is an advertising technology company specializing in video streaming and serving. It serves video ads to thousands of websites and handles close to 10 billion requests per day. \n\n“We are as much a data company as an adtech company. Our business relies on speedy and accurate data processing at massive scale. DigitalOcean provides us the perfect set of tools to operate our SaaS business profitably, while not making us feel the need to become full time system administrators. We plan to move a lot of our apps to DigitalOcean App Platform and other fully managed products.” - Roman Svichar, CTO of Vidazoo","spans":[{"start":0,"end":7,"type":"hyperlink","data":{"link_type":"Web","url":"https://vidazoo.com/"}},{"start":187,"end":583,"type":"em"}]},{"type":"paragraph","text":"We believe in meeting customers where they are. If they already have an understanding of cloud infrastructure technologies, they should be able to leverage that knowledge and get started with our products without any further ramp up.","spans":[]},{"type":"list-item","text":"Whatfix is an enterprise SaaS provider that offers a digital adoption platform to businesses. The company helps enterprises gain the full value of their investments in enterprise applications by providing real-time, interactive, and contextual guidance to users of those applications. \n\n“What we really love about the DigitalOcean platform is the ease of use. We feel like we know infrastructure and can handle most of the configuration and management. What we needed from a cloud was not bells and whistles but efficiency and reliability. DigitalOcean provides us a platform to build our apps and then gets out of the way. Just how we like it.” - Achyuth Krishna, Director of Engineering of Whatfix","spans":[{"start":0,"end":7,"type":"hyperlink","data":{"link_type":"Web","url":"https://whatfix.com/blog/driving-the-future-now-were-excited-to-announce-our-90-million-series-d-funding/"}},{"start":287,"end":648,"type":"em"}]},{"type":"paragraph","text":"We understand that scaling while maintaining reliability of applications and profitability of business is important, so we provide robust solutions which minimize downtime.","spans":[]},{"type":"list-item","text":"Centra is a SaaS-based e-commerce platform for global direct-to-consumer and wholesale e-commerce brands. Centra provides a powerful e-commerce backend that lets brands build pixel-perfect, custom designed, online flagship stores. \n\n“How do we enable our customers to create differentiated online experiences? How do we ensure their e-commerce apps stay up and running at all times? How do we scale on-demand when traffic grows or new customers come in? These are the questions that we ask ourselves every day. Thankfully, we have a partner in DigitalOcean that provides just the platform to answer those questions enabling us to guarantee 99.9% uptime for our clients.” - Martin Jensen, CEO of Centra","spans":[{"start":0,"end":6,"type":"hyperlink","data":{"link_type":"Web","url":"https://centra.com/"}},{"start":233,"end":673,"type":"em"}]},{"type":"paragraph","text":"These are just a few examples of SaaS businesses finding success on DigitalOcean. We are constantly amazed by the creativity and innovation that software builders are utilizing our platform for. If you are interested in learning more about product updates, technical deep-dives and best practices for building SaaS products and businesses, please contact us to learn how we can help you get started. ","spans":[{"start":340,"end":357,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.digitalocean.com/migrate/?utmmedium=blog","target":"_blank"}}]},{"type":"paragraph","text":"Come build with DigitalOcean!","spans":[]},{"type":"paragraph","text":"Looking to migrate your SaaS to DigitalOcean? Leverage free infrastructure credits, robust training, and technical support to ensure a worry-free migration.","spans":[{"start":0,"end":156,"type":"strong"},{"start":0,"end":156,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.digitalocean.com/migrate/?utmmedium=blog","target":"_blank"}}]},{"type":"paragraph","text":"","spans":[]},{"type":"paragraph","text":"Raman Sharma","spans":[]},{"type":"paragraph","text":"Vice President, Product & Programs Marketing","spans":[]}],"tags":[{"tag1":{"__typename":"PRISMIC_Tag","tag":"Developer Relations","_linkType":"Link.document","_meta":{"uid":"developer-relations"}}}],"author":{"__typename":"PRISMIC_Author","author_name":"Raman Sharma","author_image":{"dimensions":{"width":512,"height":512},"alt":null,"copyright":null,"url":"https://images.prismic.io/www-static/497b4b14-d192-493a-8b66-7ae176ba99f3_raman.png?auto=compress,format"},"_meta":{"uid":"raman-sharma"}},"_meta":{"uid":"how-to-scale-your-saas-product-without-breaking-the-bank"}}}}]}}},"pageContext":{"limit":12,"skip":0,"numAuthorPages":1,"currentPage":1,"uid":"shahidh_k_muhammed_hasura","data":[{"node":{"author":{"_linkType":"Link.document","author_name":"Shahidh K Muhammed, Hasura","author_image":null,"_meta":{"uid":"shahidh_k_muhammed_hasura"}},"blog_header_image":{"dimensions":{"width":784,"height":418},"alt":null,"copyright":null,"url":"https://images.prismic.io/www-static/481e269f-ebcc-43f8-b5a6-26fbef338309_CodeReview_blog.png?auto=compress,format"},"blog_headline":[{"type":"heading1","text":"Learning GraphQL By Doing","spans":[]}],"blog_post_content":[{"type":"paragraph","text":"In this tutorial, we’ll cover the basic concepts required for app developers to understand GraphQL, with the intention of learning what a GraphQL API looks like—and how it compares to REST-API equivalents—by actually trying it out.","spans":[{"start":91,"end":98,"type":"hyperlink","data":{"link_type":"Web","url":"https://graphql.org/"}}]},{"type":"paragraph","text":"This article is broken into three parts:","spans":[]},{"type":"o-list-item","text":"What is GraphQL and how it works from the client  ","spans":[]},{"type":"o-list-item","text":"Setting up a GraphQL endpoint on Postgres with Hasura and DigitalOcean  ","spans":[]},{"type":"o-list-item","text":"Exploring GraphQL queries (reads), mutations (writes), and subscriptions (real-time)","spans":[]},{"type":"heading3","text":"What is GraphQL?","spans":[]},{"type":"paragraph","text":"GraphQL is a query language and a runtime for executing the queries. Born at Facebook in 2012 and open sourced in 2015, GraphQL represents data not in terms of resource URLs, secondary keys, or join tables; but in terms of a graph of objects and the models that are ultimately used in apps, like NSObjects or JSON. GraphQL is not bound to any data exchange or transport specifications. Typically in an HTTP context, the GraphQL “query string” is POST-ed to the server and the server responds with JSON data.","spans":[]},{"type":"paragraph","text":"There are three key benefits that GraphQL users observe over REST-ful APIs:","spans":[]},{"type":"o-list-item","text":"The speed of building and iterating on the frontend app dramatically increases  ","spans":[]},{"type":"o-list-item","text":"The amount of data sent from the server to client apps reduces, making apps faster and more responsive  ","spans":[]},{"type":"o-list-item","text":"The communication between frontend and backend teams gets streamlined","spans":[]},{"type":"paragraph","text":"Here’s a GIF showing how a GraphQL client can make precise queries to a GraphQL API server to fetch exactly the data it needs and in the “shape” that it wants.","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/8a737101-cf78-49d3-9df6-412f239833a1_graphql-api.gif?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":988,"height":784}},{"type":"paragraph","text":"GraphQL adopters see these benefits because:","spans":[]},{"type":"list-item","text":"A GraphQL API allows the frontend developer to easily fetch required data across multiple resources in just a single API call instead of making multiple REST API calls.","spans":[]},{"type":"list-item","text":"A GraphQL API supports subscriptions as a standard part of the spec that makes it easy to consume real-time information on the frontend, without having to bother with setting up complex networking clients manually.","spans":[]},{"type":"list-item","text":"A GraphQL server supports introspection and has a type system that makes it possible to have great tooling for API consumers. Community tools use these introspection APIs to give you everything from auto-complete to API exploration to codegen so that you don’t have to create request/response classes for your APIs!","spans":[]},{"type":"paragraph","text":"The best way of understanding new technology like GraphQL is by trying it out. In this tutorial, we’re going to use Hasura on DigitalOcean to explore GraphQL.","spans":[{"start":116,"end":122,"type":"hyperlink","data":{"link_type":"Web","url":"https://hasura.io/"}}]},{"type":"heading3","text":"Set up a GraphQL Server","spans":[]},{"type":"paragraph","text":"Let’s first set up a GraphQL server and get a hang of it before we deep dive into more GraphQL. We’re going to use the Hasura GraphQL Engine, which is available as a 1-Click application. It is packed with a Postgres database and Caddy web server for easy and automatic HTTPS using Let’s Encrypt.","spans":[{"start":142,"end":185,"type":"hyperlink","data":{"link_type":"Web","url":"https://marketplace.digitalocean.com/apps/hasura-graphql"}},{"start":229,"end":234,"type":"hyperlink","data":{"link_type":"Web","url":"https://caddyserver.com/"}}]},{"type":"paragraph","text":"[Related: Want more Caddy? Check out the tutorial \"Deploying a Fully-automated Git-based Static Website in Under 5 Minutes\"]","spans":[{"start":0,"end":124,"type":"strong"},{"start":51,"end":122,"type":"hyperlink","data":{"link_type":"Web","url":"https://blog.digitalocean.com/deploying-a-fully-automated-git-based-static-website-in-under-5-minutes/"}}]},{"type":"paragraph","text":"Create your Hasura GraphQL Droplet, which installs all the required software and packages itself using Docker. Once the Droplet is ready, head to the Droplet IP on a browser. The Hasura console will open up, and this is where we will interact with the Hasura GraphQL Server to create the schema, test out APIs, manage data etc.","spans":[{"start":12,"end":34,"type":"hyperlink","data":{"link_type":"Web","url":"https://marketplace.digitalocean.com/apps/hasura?action=deploy&amp;refcode=c4d9092d2c48&amp;utm_source=hasura&amp;utm_campaign=do-blog"}}]},{"type":"image","url":"https://images.prismic.io/www-static/73fc240c-6622-470b-be20-b83c28937d88_graphiql_tab.png?auto=compress,format","alt":"A screenshot of the Hasura console showing the default GraphQL tab where users can try out GraphQL queries","copyright":null,"dimensions":{"width":1266,"height":912}},{"type":"paragraph","text":"A screenshot of the Hasura console showing the default GraphiQL tab where users can try out GraphQL queries.","spans":[{"start":0,"end":108,"type":"em"}]},{"type":"paragraph","text":"This tab where we try out the GraphQL queries is called GraphiQL. It serves as a playground/documentation for the GraphQL server with features like validation, autocomplete, etc.. Throughout this guide, we’ll use GraphiQL to try and test out our queries.","spans":[{"start":56,"end":64,"type":"strong"}]},{"type":"paragraph","text":"There is a public endpoint setup at https://learn-graphql.demo.hasura.app so that users can try out the steps in this tutorial without actually creating a Droplet.","spans":[{"start":36,"end":73,"type":"hyperlink","data":{"link_type":"Web","url":"https://learn-graphql.demo.hasura.app"}}]},{"type":"heading3","text":"Create a table","spans":[]},{"type":"paragraph","text":"Hasura creates the GraphQL schema by looking at Postgres schema. If there is a table called product, there will be a GraphQL type called product. We’ll come back to this again after we’ve made our first GraphQL query.","spans":[]},{"type":"paragraph","text":"Let's create a table in Postgres and get GraphQL on that, all through the Hasura console.","spans":[]},{"type":"paragraph","text":"Navigate to *Data -> Create* table on the console and create a table called `team` with the following columns:","spans":[]},{"type":"paragraph","text":"Column Name         Type","spans":[]},{"type":"paragraph","text":"id                              Integer","spans":[]},{"type":"paragraph","text":"(auto-increment)    nameText","spans":[]},{"type":"paragraph","text":"Other inputs and checkboxes like default value, nullable and, unique can be ignored. Choose `id` as the Primary Key and click the *Create* button.","spans":[]},{"type":"paragraph","text":"","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/b7927157-1a2e-433c-9157-aad62c73e40b_create_team_table.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1268,"height":834}},{"type":"paragraph","text":"Screenshot of console showing the create table screen with details filled in.","spans":[{"start":0,"end":77,"type":"em"}]},{"type":"heading3","text":"Insert sample data","spans":[]},{"type":"paragraph","text":"Once the table is created, you will be taken to the table's dashboard. Let's go to the *Insert Row* tab and add some rows. The ```[php]{`id`}``` column will be disabled as it is going to be auto-generated. You will only be able to enter the name. Once you enter one name, say Avengers, click the Save button. You will see a notification on the top right corner saying that the row has been inserted! ","spans":[{"start":296,"end":300,"type":"em"}]},{"type":"paragraph","text":"The text will remain in the name input box and the button will change to Insert Again from Save. Edit the name input box to add the next team, Justice League, and click the Insert Again button.","spans":[{"start":73,"end":85,"type":"em"},{"start":91,"end":95,"type":"em"},{"start":173,"end":185,"type":"em"}]},{"type":"image","url":"https://images.prismic.io/www-static/98025e01-5ddf-415d-bc54-276eaac7214a_insert_team.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1268,"height":428}},{"type":"paragraph","text":"Inserting rows into the table.","spans":[{"start":0,"end":30,"type":"em"}]},{"type":"paragraph","text":"Now if we go to Browse Rows tab, we can see that we have inserted two teams with name Avengers and Justice League, for which the ```[php]{`id`}``` has been auto-generated. Avengers got ```[php]{`id`}``` 1 and Justice League got ```[php]{`id`}``` 2.","spans":[{"start":16,"end":27,"type":"em"}]},{"type":"image","url":"https://images.prismic.io/www-static/6b1c8cfb-ee7e-47c4-95e9-76aa18d8b894_browse_rows_team.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1268,"height":584}},{"type":"paragraph","text":"Team table showing two rows.","spans":[{"start":0,"end":28,"type":"em"}]},{"type":"paragraph","text":"This is standard Postgres stuff. Let's jump into GraphQL now.","spans":[]},{"type":"heading3","text":"Try out GraphQL","spans":[]},{"type":"paragraph","text":"Switch to the GraphiQL tab by clicking the link on the top of the console. You will see a URL on top, which is the GraphQL API endpoint; a section to add HTTP headers; and, then the GraphiQL screen split into left and right sides. We enter the GraphQL query on the left side editor and then click the *Play* button on top and the API response appears on the right side.","spans":[]},{"type":"paragraph","text":"Copy the following GraphQL query and paste into the left side of GraphiQL. Now, click on the button with *Play* icon on it. This will send the query to the server and show the response on the right side.","spans":[]},{"type":"preformatted","text":"```[php]{`","spans":[]},{"type":"paragraph","text":"    query {  ","spans":[]},{"type":"paragraph","text":"     team {","spans":[]},{"type":"paragraph","text":"       id","spans":[]},{"type":"paragraph","text":"       name","spans":[]},{"type":"paragraph","text":"     }","spans":[]},{"type":"paragraph","text":"    }","spans":[]},{"type":"preformatted","text":"`}```","spans":[]},{"type":"paragraph","text":"The response will appear on the right.","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/dc8f5787-e7ee-4fec-83b7-fd2ca5445ceb_team_query.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1256,"height":812}},{"type":"paragraph","text":"Executing the query to get all teams.","spans":[{"start":0,"end":37,"type":"em"}]},{"type":"paragraph","text":"Woohoo! You have made your first GraphQL query on Hasura. The query above is asking the server to give information on all team objects along with the ```[php]{`id`}``` and ```[php]{`name`}``` columns.","spans":[]},{"type":"heading3","text":"GraphQL Query","spans":[]},{"type":"paragraph","text":"A GraphQL query is a string that is sent to a server to be interpreted and fulfilled, which then returns JSON back to the client. It is designed for developers of web/mobile apps (HTTP clients) to be able to make API calls to fetch the data they need from their backend APIs in a more convenient way.","spans":[]},{"type":"paragraph","text":"Let’s take a closer look at what that means. Let's say you have an API to fetch all teams. This is a typical way to do it with REST: (Request is shown on the left and response on the right).","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/89529091-c86f-4caf-a946-98cde2d1f67f_code_table_1.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":996,"height":280}},{"type":"paragraph","text":"But, with a GraphQL API, the request would look like this:","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/2f638848-2ca2-4d24-808e-1e7778d7c703_code_table_2.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":994,"height":349}},{"type":"paragraph","text":"This is what GraphiQL is doing under the hood. It is taking the query string; wrapping it in a JSON object, with a top-level query key; and, POST-ing it to the server. All GraphQL client libraries takes care of this and, as a user, we will only have to deal with the query string.","spans":[]},{"type":"paragraph","text":"Instead of GET-ing a resource at a URL qualified by the resource, we POST a GraphQL query to a single endpoint. The query defines the resource we want with any parameter of subresources. It is not JSON, but a string representation of the data we need, wrapped in a JSON body. The server responds with a JSON in the same shape of the data we requested: there is ```[php]{`team`}``` key at top level, then ```[php]{`id`}``` and ```[php]{`name`}``` nested inside.","spans":[]},{"type":"heading3","text":"Types of queries","spans":[]},{"type":"paragraph","text":"There are three different types of GraphQL queries.","spans":[]},{"type":"o-list-item","text":"Query  ","spans":[]},{"type":"o-list-item","text":"Mutation  ","spans":[]},{"type":"o-list-item","text":"Subscription","spans":[]},{"type":"paragraph","text":"Queries are typically used to fetch data, mutations for writing data and subscriptions for fetching real-time data. All three of them are collectively called “queries” again.","spans":[]},{"type":"heading3","text":"Parts of a query","spans":[]},{"type":"paragraph","text":"Each GraphQL query, whether it is a query, mutation, or subscription, fundamentally contains fields and arguments. ","spans":[]},{"type":"heading4","text":"Fields","spans":[]},{"type":"paragraph","text":"A field simply indicate that we are asking the server for that particular info. For example, in the following query that we ran earlier:","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/23b1c52d-b779-4099-9448-c1e12f09b63c_fields.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1002,"height":288}},{"type":"paragraph","text":"We ask the server for the field ```[php]{`team`}``` and its subfields ```[php]{`id`}``` and ```[php]{`name`}```, and the server returns data in the same shape as we asked for. ","spans":[]},{"type":"heading4","text":"Arguments","spans":[]},{"type":"paragraph","text":"In something like REST, we could only pass a single set of argument - as query parameters and URL segments. For example, to get a particular profile, a typical REST call would look like the following:","spans":[]},{"type":"image","url":"https://prismic-io.s3.amazonaws.com/www-static/50169033-6c0d-4d24-81d1-c1dea4ff5b41_argument_1.png","alt":null,"copyright":null,"dimensions":{"width":1003,"height":129}},{"type":"paragraph","text":"Or like this:","spans":[]},{"type":"image","url":"https://prismic-io.s3.amazonaws.com/www-static/b1df8108-4511-44aa-9ae4-5d801c763829_argument_2.png","alt":null,"copyright":null,"dimensions":{"width":998,"height":137}},{"type":"paragraph","text":"With GraphQL, every field can take any arbitrary number of arguments as defined by the schema. The REST API above would look like this with GraphQL:","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/efcd3838-d8d0-4e45-9246-59260243ef8c_argument_3.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":996,"height":219}},{"type":"paragraph","text":"Try this out in GraphiQL.","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/9e140e9d-5a6e-4ae5-b29d-c13f043202ac_team_where_query.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1256,"height":747}},{"type":"paragraph","text":"A query using the where argument.","spans":[{"start":0,"end":33,"type":"em"}]},{"type":"paragraph","text":"Similarly, there are many other arguments available for queries, like ```[php]{`order_by`}```, ```[php]{`limit`}```, ```[php]{`offset`}``` etc. You can try them out in GraphiQL: use Ctrl/Cmd+Space to open up the auto-complete suggestions.","spans":[]},{"type":"heading3","text":"Query variables","spans":[]},{"type":"paragraph","text":"But how do we parametrize this? Since the query is a string, a naive way would be to implement string interpolation. But this can introduce bugs and is not efficient.","spans":[]},{"type":"paragraph","text":"Any GraphQL query can be parametrized by defining variables. Variables can be used in the query string and the values of those variables can be sent in a separate object. This makes it easy to re-use queries by using different set of variables instead of something like string interpolation. Variables need to be defined before they can be used and while defining the type also need to be provided. ","spans":[]},{"type":"paragraph","text":"Here is an example:","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/c8d5f781-31f5-4cae-b01d-572913f3278a_query.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":995,"height":307}},{"type":"paragraph","text":"The first column contains the query, the column below that contains the variables object, and the right column contains the response, as represented in GraphiQL. Try this query out and see the response:","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/2d6f52f5-de77-4d8b-814e-4127ca5926a0_team_variable_query.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1256,"height":809}},{"type":"paragraph","text":"A query along with variables.","spans":[{"start":0,"end":29,"type":"em"}]},{"type":"paragraph","text":"Here we are defining a variable called ```[php]{`id`}```, as denoted by the prefix ```[php]{`$`}``` and it is of type ```[php]{`Int`}```. The ```[php]{`!`}``` indicates that this variable is mandatory for this query to be executed. The client typically send the variables in a JSON object with key ```[php]{`variables`}``` in the JSON POST body along with the ```[php]{`query`}``` string.","spans":[]},{"type":"paragraph","text":"The POST body would look something like this:","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/9399d71a-5308-4790-b6dd-04711cc60253_query_2.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":979,"height":172}},{"type":"paragraph","text":"Now, the query string need only be defined once in your application and for various ```[php]{`id`}```s, the variables can be changed as required.","spans":[]},{"type":"heading3","text":"Query","spans":[]},{"type":"paragraph","text":"A query is a GraphQL query typically used to fetch data. All the examples we saw earlier are \"queries.\" For example, when we get the team with ```[php]{`id`}``` 2:","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/c5f35492-6e4b-4aa1-a463-078825b971ba_query_3.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":993,"height":217}},{"type":"heading3","text":"Multiple root nodes","spans":[]},{"type":"paragraph","text":"Let's take a look at how we can query multiple tables (or nodes) in the same query. For that, let us create a new table first.","spans":[]},{"type":"paragraph","text":"Go back to the Data tab and create a new table called ```[php]{`superhero`}``` with the following columns:","spans":[{"start":15,"end":19,"type":"em"}]},{"type":"paragraph","text":"Column Name      Type","spans":[]},{"type":"paragraph","text":"id                            Integer","spans":[]},{"type":"paragraph","text":"(auto-increment)   nameText","spans":[]},{"type":"paragraph","text":"team_id                   Integer","spans":[]},{"type":"paragraph","text":"Other inputs and checkboxes like default value, nullable, and unique can be ignored. Choose ```[php]{`id`}``` as the Primary Key and click the Create button.","spans":[{"start":143,"end":149,"type":"em"}]},{"type":"image","url":"https://images.prismic.io/www-static/57158fac-75d0-43e1-ae2a-85f18b57b2b4_superhero_table.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1268,"height":875}},{"type":"paragraph","text":"Creating the superhero table.","spans":[{"start":0,"end":29,"type":"em"}]},{"type":"paragraph","text":"Once the table is created, you'll be taken to the Modify tab. Let's switch to Insert Rows tab and insert some rows like we did last time.","spans":[{"start":50,"end":56,"type":"em"},{"start":78,"end":89,"type":"em"}]},{"type":"paragraph","text":"The ```[php]{`id`}``` column will be disabled like last time, since it will be auto-generated by Postgres. Let's enter the ```[php]{`name`}``` and ```[php]{`team_id`}``` for each super hero. If we scroll back, ```[php]{`team_id`}``` is 1 for Avengers and 2 for Justice League.","spans":[]},{"type":"paragraph","text":"name                     team_id","spans":[]},{"type":"paragraph","text":"Captain America  1","spans":[]},{"type":"paragraph","text":"Black Widow        1","spans":[]},{"type":"paragraph","text":"Batman                 2","spans":[]},{"type":"paragraph","text":"Wonder Woman   2","spans":[]},{"type":"paragraph","text":"Once we add the data, using GraphQL, we can fetch data from multiple nodes (tables) in the same query. Copy the following query into GraphiQL and hit the Play button.","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/f012daeb-3f0d-4ad9-8019-7b3a97aa264e_query_4.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":995,"height":679}},{"type":"image","url":"https://images.prismic.io/www-static/31324400-3d0f-4426-a45c-23105e3d9f27_multi-nodes.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1256,"height":1098}},{"type":"paragraph","text":"Using multiple nodes in the same GraphQL query.","spans":[{"start":0,"end":47,"type":"em"}]},{"type":"paragraph","text":"Similarly how many ever such top-level nodes can be included in a single query. This applies to mutations too, but subscription spec limits subscriptions to contain only one top-level node.","spans":[]},{"type":"heading3","text":"Querying related data","spans":[]},{"type":"paragraph","text":"For data that are related and are in multiple tables, we can define relationships over the columns and query them in a nested format. For e.g. let us see how we can query for the team and get all the superheroes in that team.","spans":[]},{"type":"paragraph","text":"In order to do this, we need to create a relationship between ```[php]{`team`}``` and ```[php]{`superhero`}``` tables. We already know that ```[php]{`team_id`}``` is our link. In relational database modelling, a foreign key constraint is added on this column to indicate the values in this columns should also be present as the ```[php]{`id`}``` column in ```[php]{`team`}``` table. Let's first add that constraint. Note that this is totally optional and will only act as a constraint, as a foreign key is not required to create a relationship. ","spans":[]},{"type":"paragraph","text":"Head to the Data tab, click on the ```[php]{`superhero`}``` table on the left and then go to the Modify tab. On this tab, click on the Edit button next to ```[php]{`team_id`}``` column. This will open up certain properties of that column. The last one among them will be a Foreign Key. Tick the checkbox there and then choose ```[php]{`team`}``` as the reference table and ```[php]{`id`}``` as the reference column. Then click the Save button.","spans":[{"start":12,"end":16,"type":"em"},{"start":97,"end":103,"type":"em"},{"start":135,"end":139,"type":"em"},{"start":431,"end":435,"type":"em"}]},{"type":"image","url":"https://images.prismic.io/www-static/8f54f674-f23f-431a-a58d-5836e3f77ed8_add-fk-team-id.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1268,"height":1012}},{"type":"paragraph","text":"Creating a Foreign Key constraint on team_id column","spans":[{"start":0,"end":51,"type":"em"}]},{"type":"paragraph","text":"Once the save has happened, a notification appears on the top right saying the constraint is created.","spans":[]},{"type":"paragraph","text":"Now, head to the ```[php]{`team`}``` table by clicking on the left sidebar. Go to the Relationships tab and you'll see a new array relationship suggestion.","spans":[{"start":86,"end":99,"type":"em"}]},{"type":"image","url":"https://images.prismic.io/www-static/3babf3f7-7f01-4bf0-acc4-a2ad40d003a8_team-array-rel-suggestion.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1268,"height":605}},{"type":"paragraph","text":"Array relationship suggestion on the team table","spans":[{"start":0,"end":47,"type":"em"}]},{"type":"paragraph","text":"Click on the Add button here. A name will be auto-filled for the relationship, let's change it to just ```[php]{`superheroes`}``` and click the Save button.","spans":[{"start":13,"end":16,"type":"em"},{"start":144,"end":148,"type":"em"}]},{"type":"image","url":"https://images.prismic.io/www-static/146153ac-de50-419b-b905-482fdb8206fb_team-array-rel-save.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1268,"height":617}},{"type":"paragraph","text":"Entering the array relationship name as superheroes","spans":[{"start":0,"end":51,"type":"em"}]},{"type":"paragraph","text":"You'll see a notification on the top right saying the relationship is saved.","spans":[]},{"type":"paragraph","text":"Now, head back to GraphiQL by clicking on the top bar and copy paste the following query and click *Play* button to execute.","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/706216b8-225f-41de-8dee-ff426f333037_query_5.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":992,"height":475}},{"type":"image","url":"https://images.prismic.io/www-static/e78d2dd4-50e1-4c3c-b257-bc724df2edf5_related-query.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1256,"height":1012}},{"type":"paragraph","text":"Querying related data","spans":[{"start":0,"end":21,"type":"em"}]},{"type":"paragraph","text":"One query can traverse related objects and their fields, letting clients fetch lots of related data in one request, instead of making several round trips as one would need in a classic REST architecture.","spans":[]},{"type":"heading3","text":"Mutation","spans":[]},{"type":"paragraph","text":"In GraphQL realm, a mutation is a type of query that typically mutates data, like database insert/update/deletes. REST equivalents would be PUT/POST/DELETE requests. Let's say I need to add a new ```[php]{`superhero`}``` to my database. A REST request would look like the following:","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/d06278d9-5850-48c2-8a2c-606eb58856c4_Post_1.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":994,"height":192}},{"type":"paragraph","text":"Now, let's take a look at the GraphQL equivalent:","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/3708965e-a4e2-464c-a299-0551b9644513_Post_2.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":994,"height":323}},{"type":"paragraph","text":"We can also have the name as a variable so that we do not have to manipulate strings to insert different Avengers.","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/efbc3ddf-bd3f-49d6-a35f-43ddcd034364_mutation.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":993,"height":452}},{"type":"paragraph","text":"Like we mentioned before, the first column is the query, the one on the bottom are the variables, and the right columns shows us the response.","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/4ab28403-6564-4f31-9fa3-f7a8afd3d098_inser-hero-mutation.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1256,"height":927}},{"type":"paragraph","text":"A mutation inserting a new superhero","spans":[{"start":0,"end":36,"type":"em"}]},{"type":"paragraph","text":"Like queries, we can mix multiple mutations in the same request. You can also insert related data in a single mutation.","spans":[]},{"type":"heading3","text":"Subscription","spans":[]},{"type":"paragraph","text":"Subscriptions provide real-time capabilities in GraphQL. Traditionally there are two options to obtain live data on the client side. One is calling the REST endpoint at regular intervals of time till we get the desired state (also called polling) and the other is to push an event to the client from the server using websockets.","spans":[]},{"type":"paragraph","text":"Polling is a highly inefficient process and implementing websockets are a nightmare. GraphQL subscriptions also works over websockets, but GraphQL community has standardised what the language the websocket server and client should speak. Because of that, all clients and servers are compatible with each other and the integration is seamless.","spans":[]},{"type":"paragraph","text":"Any query can be converted into a subscription with Hasura. For example, the query to get all Avengers can be made into a subscription like this, and if a web component is rendered (say React) using this data, the component re-renders when a new item gets added. This can be experimented on easily by opening two GraphiQL windows: running a subscription on one window, while try making a mutation on the other one.","spans":[]},{"type":"paragraph","text":"The subscription on the left column, when copied onto GraphiQL and executed, is asking the server to send changes on the ```[php]{`team`}``` table, particularly for the one with ```[php]{`id`}``` equals 1, as and when they happen. The mutation on the right, when executed, will insert a new superhero to the ```[php]{`superhero`}``` table. Since the two tables are related through ```[php]{`team_id`}```, Hasura notices that there is a new superhero that has been added to team 1 and pushed that information onto the client. The result of the subscription updates automatically—all in real-time.","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/a69795d8-deb3-4339-a1a7-3281651ab42d_subscription.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1000,"height":325}},{"type":"image","url":"https://images.prismic.io/www-static/fc71f1c3-59f2-4de5-9fc2-43cefb109399_Peek-2019-02-19-18-16.gif?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":1600,"height":812}},{"type":"paragraph","text":"A GIF showing subscriptions","spans":[{"start":0,"end":27,"type":"em"}]},{"type":"paragraph","text":"Under the hood, the GraphQL client and the server communicate over websockets and messages are transferred without any extra involvement from the user. When used in a application, the client library takes care of all the plumbing for the user.","spans":[]},{"type":"heading3","text":"The GraphQL Schema","spans":[]},{"type":"paragraph","text":"Documenting APIs is very important for team collaboration and feature velocity. The backend team works on the API, documents it, and passes it down to the frontend team. But, by the time the frontend team gets to use the APIs, the documentation could be out of date, missing, or plain wrong, since a separate human process is required for maintaining docs.","spans":[]},{"type":"paragraph","text":"GraphQL attempts to address this issues by introducing a type system for the API: the GraphQL schema. It talks about what fields the client can query, whether it is an integer or a string, what are the parameters for this mutation, is this parameter required or not etc.","spans":[]},{"type":"paragraph","text":"In fact, you could make a GraphQL query to get this schema. This is called introspection, where the server publishes its own schema and clients can query it when required. This opens up lot of possibilities, including type safety for your API. Clients can look at this schema and generate code required for making idiomatic type safe API calls and errors could be caught at compile time itself instead of at runtime (for clients written in typed languages). IDEs can exploit this and show live feedback like autocomplete and validation on the queries written by the developer.","spans":[]},{"type":"paragraph","text":"Try out the following query:","spans":[]},{"type":"image","url":"https://images.prismic.io/www-static/28780361-d364-430e-b833-29948f61228d_query_6.png?auto=compress,format","alt":null,"copyright":null,"dimensions":{"width":897,"height":853}},{"type":"paragraph","text":"There is a *Docs* button on the top right corner of GraphiQL tab where you can browse this schema. It is helpful in figuring out what are the queries/mutations/subscriptions supported by the server and what their arguments and return types are.","spans":[]},{"type":"heading3","text":"Conclusion","spans":[]},{"type":"paragraph","text":"In this tutorial, we learned about GraphQL by setting up a GraphQL server over Postgres and by trying out some GraphQL queries, mutations, and subscriptions. We have gone through the types of GraphQL queries and the different parts within a query. We also walked though how a GraphQL schema helps building intelligent tools for the ecosystem, which increases developer productivity.","spans":[]},{"type":"paragraph","text":"As next steps, you'd want to integrate GraphQL with your application, including authentication and authorization. Check out the resources below for further reading.","spans":[]},{"type":"heading3","text":"Resources","spans":[]},{"type":"list-item","text":"Building your schema","spans":[{"start":0,"end":20,"type":"hyperlink","data":{"link_type":"Web","url":"https://docs.hasura.io/1.0/graphql/manual/schema/index.html"}}]},{"type":"list-item","text":"GraphQL Queries","spans":[{"start":0,"end":15,"type":"hyperlink","data":{"link_type":"Web","url":"https://docs.hasura.io/1.0/graphql/manual/queries/index.html"}}]},{"type":"list-item","text":"GraphQL Mutations","spans":[{"start":0,"end":17,"type":"hyperlink","data":{"link_type":"Web","url":"https://docs.hasura.io/1.0/graphql/manual/mutations/index.html"}}]},{"type":"list-item","text":"GraphQL Subscriptions","spans":[{"start":0,"end":21,"type":"hyperlink","data":{"link_type":"Web","url":"https://docs.hasura.io/1.0/graphql/manual/subscriptions/index.html"}}]},{"type":"list-item","text":"Event Triggers","spans":[{"start":0,"end":14,"type":"hyperlink","data":{"link_type":"Web","url":"https://docs.hasura.io/1.0/graphql/manual/event-triggers/index.html"}}]},{"type":"list-item","text":"Remote Schemas","spans":[{"start":0,"end":14,"type":"hyperlink","data":{"link_type":"Web","url":"https://docs.hasura.io/1.0/graphql/manual/remote-schemas/index.html"}}]},{"type":"list-item","text":"Authentication/Access control","spans":[{"start":0,"end":29,"type":"hyperlink","data":{"link_type":"Web","url":"https://docs.hasura.io/1.0/graphql/manual/event-triggers/index.html"}}]},{"type":"list-item","text":"Database Migrations","spans":[{"start":0,"end":19,"type":"hyperlink","data":{"link_type":"Web","url":"https://docs.hasura.io/1.0/graphql/manual/migrations/index.html"}}]},{"type":"list-item","text":"Hasura GraphQL Guides","spans":[{"start":0,"end":21,"type":"hyperlink","data":{"link_type":"Web","url":"https://docs.hasura.io/1.0/graphql/manual/guides/index.html"}}]},{"type":"heading3","text":"Community and Support","spans":[]},{"type":"paragraph","text":"If you have any questions regarding this tutorial or using Hasura, please reach out to the Hasura community:","spans":[]},{"type":"list-item","text":"Github","spans":[{"start":0,"end":6,"type":"hyperlink","data":{"link_type":"Web","url":"https://github.com/hasura/graphql-engine"}}]},{"type":"list-item","text":"Discord (community forum)","spans":[{"start":0,"end":25,"type":"hyperlink","data":{"link_type":"Web","url":"https://discord.gg/hasura"}}]},{"type":"list-item","text":"Twitter","spans":[{"start":0,"end":7,"type":"hyperlink","data":{"link_type":"Web","url":"https://twitter.com/hasurahq"}}]}],"blog_post_date":"2019-03-12","tags":[{"tag1":{"tag":"Marketplace","_linkType":"Link.document","_meta":{"uid":"marketplace"}}}],"_meta":{"uid":"learning-graphql-by-doing"}}}]}}}