GraphQL - Big Nerd Ranch Wed, 16 Nov 2022 21:31:36 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.5 Testing Your GraphQL Server https://bignerdranch.com/blog/testing-your-graphql-server/ Tue, 08 Dec 2020 21:21:52 +0000 https://www.bignerdranch.com/?p=4632 GraphQL presents significant challenges for the backend developer. It is on the server that most of the complexities of using this exciting technology are revealed. A good set of testing best practices and tools can go a long way towards managing that complexity.

The post Testing Your GraphQL Server appeared first on Big Nerd Ranch.

]]>
We’re continuing our GraphQL series with a look at how to best test your GraphQL server. If you’d like a bit of a refresher, check out our What is GraphQL? post.

GraphQL provides the ability to expose APIs in a way that is flexible and performant for clients. This flexibility can come at a cost in complexity for server implementations. While there are many options available in terms of technology stacks for implementing GraphQL, one of the most popular is Node.js and Javascript. Here is a link to an article discussing Testing on Node.js in general.

Below is a GraphQL server app built on Node.js, Apollo and Express.

import express from 'express'
import { graphqlExpress, graphiqlExpress } from 'apollo-server-express'

import { schema } from './schema.js'

// Initialize the app
const app = express()

// The GraphQL endpoint
app.use('/graphql', express.json(), graphqlExpress({ schema }))

// GraphiQL, a visual editor for queries
app.use('/graphiql', graphiqlExpress({ endpointURL: '/graphql' }))

// Start the server
app.listen(3000, () => {
  console.log('Go to http://localhost:3000/graphiql to run queries!')
})

You will be working with the following GraphQL definition defined in schema.gql.

type Book {
  title: String!
  author: String!
}

type Query {
  getBooks: [Book]
  getAuthors: [String]
}

input BookInput {
  title: String!
  author: String!
}

type Mutation {
  addBook(input: BookInput!): Book
}

The executable schema loaded into graphqlExpress needs two things: the file containing the GraphQL types and the resolvers for getBooksgetAuthors and addBook.

import { resolvers } from './resolvers.js'
import { makeExecutableSchema } from 'graphql-tools'

import fs from 'fs'
import path from 'path'

export const typeDefs = fs.readFileSync(path.join(__dirname, '.', 'schema.gql'), 'utf8')

// Put together a schema
export const schema = makeExecutableSchema({
  typeDefs,
  resolvers,
})

Here is your incredibly sophisticated yet lightweight in-memory database of Books that will support the resolvers.

export const books = [
  {
    title: "Harry Potter and the Sorcerer's stone",
    author: 'J.K. Rowling',
  },
  {
    title: 'Jurassic Park',
    author: 'Michael Crichton',
  }
]

Finally, the resolvers themselves that will provide and mutate your book data.

import { books } from './models.js'

export const resolvers = {
  Query: {
    getBooks: () => books,
    getAuthors: () => {
      return books.map (book => {
        return book.author
      })
    }
  },
  Mutation: {
    addBook: (_, args) => {
      const book = { title: args.input.title, author: args.input.author }
      books.push(book)
      return book
    }
  }
}

There are four primary areas of interest with server-side GraphQL. I’ve demonstrated testing strategies for each part below.

  • Schema testing
  • Query Testing
  • Mutation Testing
  • Resolver Testing

Now, let’s see them in action.

Schema Testing

Chai.js is an assertion library built for Node in general, rather than specifically for GraphQL. Use assertions to verify your schema was loaded correctly.

import { describe, it } from 'mocha'
import chai from 'chai'
import { schema } from '../schema.js'

chai.should()

describe('Test Static Schema Snapshot', () => {
    
    it('schema should contain types', () => {
      chai.assert.isNotNull(schema.getType("Book"))
      chai.assert.isDefined(schema.getType("Book"))
    })
    
    it('scheme should not contain unregistered types', () => {
      chai.assert.isUndefined(schema.getType("NotADefinedType", "Type should not be defined"))
    })
})

These static tests could be written with any unit testing library, so feel free to substitute your favorite.

Query Testing

To start testing GraphQL queries, use the easygraphql-tester library. The library can be used to test all kinds of resolvers, queries, mutations, and subscriptions, but start by testing the getBooks query.

First, create a tester object from your schema.

import { describe, it, before } from 'mocha'
import { resolvers } from '../resolvers.js'
import { books } from '../models.js'

import EasyGraphQLTester from 'easygraphql-tester'
import { typeDefs } from '../schema.js'

describe('Test Queries', () => {
    let tester
        
    before(() => {
        tester = new EasyGraphQLTester(typeDefs, resolvers)
    })
    
    // ...tests go here
})

Next, create a test which calls the allBooks query and verify that the call is successful (by passing in true) and that it returns the correct book data (by providing the expected data).

it('Should pass if the query is valid', () => {
  const validQuery = `
  {
    getBooks {
      title
    }
  }
  `
  tester.test(true, validQuery, {
    books: books
  })
})

Finally, create a failing query by asking GraphQL for a property that doesn’t exist on Book.

it('Should fail if the query is invalid', () => {
  const invalidQuery = `
  {
    getBooks {
      # Not a field!
      publicationDate
    }
  }
  `
  tester.test(false, invalidQuery)
})

Mutation Testing

An important part of GraphQL is the ability to modify system state using the concept of a Mutation. A Mutation is a defined type that declares a mutation API with given inputs and expected outputs.

Using the following Mutation definition.

input BookInput {
  title: String!
  author: String!
}

type Mutation {
  addBook(input: BookInput!): Book
}

Define a series of tests to validate your Mutation fails appropriately when missing the required input. Also, provide a test that verifies that your system is in the correct state after performing a mutating action. In this case by adding a Book to your in-memory Book database.

import { describe, it, before } from 'mocha'
import { expect } from 'chai'

import EasyGraphQLTester from 'easygraphql-tester'
import fs from 'fs'
import path from 'path'
import { books } from '../models.js'
import { resolvers } from '../resolvers.js'

const schemaCode = fs.readFileSync(path.join(__dirname, '.', 'schema.gql'), 'utf8')

describe('Test Mutation', () => {
  let tester

  before(() => {
    tester = new EasyGraphQLTester(schemaCode, resolvers)
  })

  describe('Should throw an error if variables are missing', () => {
    it('Should throw an error if the variables are missing', () => {
      let error
      try {
        const mutation = `
                mutation AddBook($input: BookInput!) {
                  addBook(input: $input) {
                    title
                    author
                  }
                }
              `
        tester.mock(mutation)
      } catch (err) {
        error = err
      }

      expect(error).to.be.an.instanceOf(Error)
      expect(error.message).to.be.eq('Variable "$input" of required type "BookInput!" was not provided.')
    })
  })

  describe('Should add a book', () => {
    it('Should add Pet Cemetary to the list of books', () => {
      const mutation = `
              mutation AddBook($input: BookInput!) {
                addBook(input: $input) {
                  title
                  author
                }
              }
            `
      const bookCount = books.length
      tester.graphql(mutation, undefined, undefined, {input: {
        title: 'Pet Cemetary',
        author: 'Stephen King'
     }}).then(result => {
       expect(books.length).to.be.eq(bookCount+1)
     })
     .catch(err => console.log(err))
    })
  })
})

Resolver Testing

Resolvers are pure functions (no side effects) that support a query’s ability to fetch and transform results based on their requirements. In this example, define a simple getAuthors resolver that is implemented via a map transformation over your books database. Invoking the getAuthors query will resolve to this function at runtime.

export const resolvers = {
  Query: {
    getBooks: () => books, // Access your real database of books
    getAuthors: () => {
      return books.map (book => {
        return book.author
      })
    }
  } ...
}

Testing this resolver is demonstrated below. You construct a query specification for the getAuthors query and execute against schema graph. You can then inspect the results of the query via promise fulfillment and perform standard chai assertions on the state.

import { describe, it, before } from 'mocha'
import { expect } from 'chai'

import EasyGraphQLTester from 'easygraphql-tester'
import { typeDefs } from '../schema.js'
import { books } from '../models.js'
import { resolvers } from '../resolvers.js'

describe("Test Resolvers", () => {
    let tester;
    before(() => {
      tester = new EasyGraphQLTester(typeDefs, resolvers);
    });
  
    it("should return expected values", async () => {
        const query = `
        {
            getAuthors
        }`
  
      const args = {}  
      const result = await tester.graphql(query, {}, {}, args)
      
      expect(result.data.getAuthors.length).to.be.eq(books.length)
      expect(result.data.getAuthors[0]).to.be.eq("J.K. Rowling")
    });
  });

With the tools above you can effectively manage the complexities of GraphQL on the server. The ability to validate your schema definitions, queries, mutations, and resolvers are valuable components ensuring quality in your systems and confidence when you need to introduce changes to your code.

If you’d like to explore more of what GraphQL can offer, check out our posts on Building a GraphQL Server with Java and GraphQL versus REST. Also, if you aren’t sure if GraphQL is the best fit, check out Is GraphQL Right for My Project?

The post Testing Your GraphQL Server appeared first on Big Nerd Ranch.

]]>
GraphQL versus REST https://bignerdranch.com/blog/graphql-versus-rest/ Tue, 01 Dec 2020 11:00:05 +0000 https://www.bignerdranch.com/?p=4622 GraphQL and REST paradigms can both be used to create scalable and useful APIs, but GraphQL has some alternative approaches that make a big difference for developers.

The post GraphQL versus REST appeared first on Big Nerd Ranch.

]]>
GraphQL is a new way for developers to think about APIs. GraphQL and REST paradigms can both be used to create scalable and useful APIs, but GraphQL has some alternative approaches that make a big difference for developers. The core components of each API strategy are approached differently. This blog post focuses on three key differences between REST and GraphQL that give GraphQL an edge, especially for developer productivity.

Be sure to check out our post, What is GraphQL? if you’d like a refresher.

No more over/under fetching

Resources are one of the key ideas in REST. For developers using REST, the approach is to identify each resource by a URL. By contrast, developers are generally expected to use a single endpoint for GraphQL APIs. An API using REST to allow access to a book resource may return something like the following when clients send a GET request to the /books/1 path:

{
  "title": "Timeless Laws of Software Development",
  "author": {
    "first_name": "Jerry",
    "last_name": "Fitzpatrick"
  },
  "illustrator": {
    "first_name": "Jennifer",
    "last_name": "Kohnke"
  },
  "id": 1,
  "url": "/books/1",
  "categories": ["software", "testing"]
}

Everything about the above response to the GET request was determined by the API. Any time developers want to fetch details about a book they can generally expect the same type of response using the /books/{id} endpoint.

GraphQL is very different when it comes to how it interprets the idea of resources. In GraphQL, the concept of a resource is generally expressed as a type using the GraphQL schema language. For the book API in the example above, GraphQL would express the book resource as a type:

type Book {
  id: ID
  title: String
  illustrator: Illustrator
  author: Author
  categories: [String]
}

The Book type describes the kind of data available but notably lacks a URL that specifies how to retrieve a particular book by id. While confusing if you are new to GraphQL, the reason for lacking a URL is because GraphQL separates resources from how they are retrieved. In practice, this means backend developers must specify a Query type that exposes the ability to fetch books instead of determining a URL pattern to expose as an endpoint. In addition to the Book type, adding the following replaces the concept of a /books/{id} endpoint in REST:

type Query {
  book(id: ID!): Book
}

To get details about any book resource, any client can request the Book resource and only specific fields they need for a book. Instead of querying via an endpoint, developers would send a GET request to the API that looks something like this:

/graphql?query={ book(id: "1") { title } }

Note that instead of specifying the resource in the URL, as with REST, the GraphQL request for a book resource is in a different format. Developers sending this query to a GraphQL endpoint (e.g. /graphql) would retrieve something like the following:

{
  "title": "Timeless Laws of Software Development"
}

The shape and size of the GraphQL query is determined by the nature of the request. Developers working on clients consuming a GraphQL API get the benefit of being able to decide what data they want from the API. If a developer wanted more data, such as the name of the illustrator of a book, then they would simply request those additional fields from the API.

Typed queries

GraphQL’s schema language allows for the API to specify types for every field associated with an object. In addition to some special types, it also supports specifying custom object types as well. Developers are prone to mistakes when developing clients for APIs, especially when documentation on the shape of an endpoint’s response is lacking. REST has some solutions for mapping endpoints to fluent interfaces such as TypedRest, but GraphQL’s schema language comes with a type system baked in. Tools can parse the types specified for return values from queries to make tooling that catches errors early.

For example, the query that was looked at earlier can be easily understood by developers and tooling:

type Query {
  book(id: ID!): Book
}

Developers new to this API simply need to investigate the Book object type to know what will be returned by the above query. More information can be provided for introspection in a description, and we’ll cover that in a moment.

The baked-in type system has extensive documentation and is also used by developers to create tools that prevent errors during development. Server-side tools such as Apollo Server use the type system for introspection and even allows developers to test and preview queries in a playground. VSCode has a plugin called Graphql for VSCode that provides linting, syntax highlighting, and even schema validation. To take full advantage of the power of GraphQL’s type system and typed queries out of the box all you need to do is reach for a plugin in your IDE.

Self-documenting nature

GraphQL’s schema language can be checked for validity. This allows developers to reference a GraphQL API’s schema as a source of truth. While poor naming of object types and fields is possible, good naming within a GraphQL schema results in APIs that are self-documenting. Naming is probably one of the most important things to get right in a GraphQL project because tools and developers rely on the type system to explain the shape and nature of the data they are requesting.

For REST APIs, Swagger is a good option for producing publishable documentation. However, GraphQL treats documentation as a first-class feature of its specification, meaning developers don’t need to reach for external documentation tools or generators. Up-to-date and accurate descriptions of fields and types can be pulled directly from the GraphQL schema! For example, a schema could be documented using CommonMark in code as follows:

"""
The representation for books available in the catalog
"""
type Book {
  "Unique identifer"
  id: ID
  "The name of the book as listed in the catalog"
  title: String
  "The illustrator listed in the catalog for the book"
  illustrator: Illustrator
  "The author listed in the catalog for the book"
  author: Author
  "The categories this book belongs to on the website"
  categories: [String]
}

"""
Represents an illustrator of a book
"""
type Illustrator {
  first_name: String
  last_name: String
}

"""
Represents an author of a book
"""
type Author {
  first_name: String
  last_name: String
}

type Query {
  """
  Retrieves a book by ID
  """
  book("The unique `ID` of a book" id: ID!): Book
}

The description feature of the GraphQL specification, well-named object types, and descriptive fields ensures the documentation for a GraphQL API is always publishable to tools and future developers.

For queries and mutations, developers can easily see what fields are available. Entire IDEs are being developed just for GraphQL as well that leverages the language’s support for introspection. GraphiQL is one such IDE developed by the GraphQL Foundation.

Now that we’ve looked at REST vs GraphQL, you might be wondering if GraphQL is something that you want to tackle with your next project. Check out Is GraphQL Right for My Project? to get a good idea of the questions you should ask prior to jumping in.

The post GraphQL versus REST appeared first on Big Nerd Ranch.

]]>
Building a GraphQL Server with Java https://bignerdranch.com/blog/building-a-graphql-server-with-java/ Fri, 20 Nov 2020 13:56:27 +0000 https://www.bignerdranch.com/?p=4615 If you want to be a rebel and implement GraphQL in Java, here's the guide for you!

The post Building a GraphQL Server with Java appeared first on Big Nerd Ranch.

]]>
For the purposes of this article, I’m going to assume you know what GraphQL is. If not, check out our first post in our GraphQL series, What is GraphQL.

JavaScript (NodeJS) seems to be the most popular implementation of GraphQL servers, but if you want to be a rebel and do it in Java then this is the right place for you! In this post, you’ll learn:

  1. What’s going on in the open-source community around Java and GraphQL
  2. A brief intro to some of the more popular Java libraries to help you decide which ones to utilize for building your GraphQL API.

Java/GraphQL Open-Source Landscape

GraphQL is a fairly new technology, having been released publicly by Facebook in 2015. As I mentioned previously, JavaScript appears to be the most popular implementation of GraphQL. Understandably so since, at that time, Facebook also released the JavaScript implementation for the GraphQL specification. I didn’t go into great depth to validate this conclusion with hard statistics, but I did take a quick look at the Github numbers on the various open-source projects that support GraphQL.

Here are some Github stats for the JavaScript implementation of GraphQL (as of Oct 9th, 2020)

JavaScript GraphQL usage numbersand the corresponding stats for the Java implementation of GraphQL (as of Oct 9th, 2020)

Java GraphQL usage numbersAll that to say, community support is not quite as strong for implementing a GraphQL server in Java as opposed to JavaScript. From what I’ve found, the documentation and tutorials for doing this in Java are a little rough around the edges. My hope is that the information in this post will save you some time getting up to speed on your options.

GraphQL supporting Java Libraries

graphql-java

This is the quasi-official Java implementation of the GraphQL specification. All the libraries I will talk about next build on top of this one. In my opinion, using it directly is very clunky and verbose, but you can certainly give it a try using their Getting Started Tutorial.

graphql-spqr

The acronym SPQR (pronounced like speaker) stands for “Schema Publisher & Query Resolver.” Basically, with this library, you can slap some annotations on the service and data classes, drop some boiler-plate code in the startup logic of the app, and you’ve got an exposed GraphQL API! No need to even write a GraphQL schema.

This is a very attractive option because you can get it going very quickly, especially if you’re adding GraphQL to an existing Java service. That being said, there are some trade-offs to this code-first approach. For one, this approach is the opposite of the schema-first (similar to “API first“) approach that GraphQL purports. As a result, you risk losing some benefits that come from a well-defined API contract. Some examples include having reduced ability for teams to work in parallel, a steeper learning curve for new developers, and decreased reuse across APIs. See this great article from Swagger for more details.

graphql-java-tools

Similar to graphql-spqrgraphql-java-tools also makes it easy to wire up your Java classes to the GraphQL schema, but this library takes more of a schema-first approach.

It helps you avoid a lot of the boiler-plate code and clunky data fetchers that are needed from graphql-java. Instead, you:

  1. Define your GraphQL schema
  2. Create some “Resolvers” to expose your data classes
  3. Wire your Resolvers and schema file into the app’s startup code.

Of course, the downside is that it’s slightly more work than graphql-spqr, since you have to actually build the GraphQL schema, but I believe there are some benefits to thinking through your schema/contract first before writing/rewriting code.

graphql-spring-boot

Here you’ll find a Spring Boot starter that provides graphql-java-tools in a Springified (because that’s a word) manner!

This even further reduces the boilerplate configuration needed since this reduces step 3 in the graphql-java-tools section down to creating beans out of your Resolvers. The Spring Boot starter will automatically scan the classpath to find your GraphQL schema file, making it a fairly minimal amount of work to get your GraphQL schema connected to the underlying Java classes.

Conclusion

You may have picked up on this already, but, of these libraries, my preference is graphql-spring-boot. It supports a schema-first approach, which is more in line with GraphQL’s strategy and advantages. Also, it does a lot of the boilerplate configuration for you, making it simple to expose your Java service as a GraphQL API.

I do want to clarify that I have not gone over every open-source Java library that supports building a GraphQL API; there are way too many to fit into a single article. I tried to focus on the most core/popular frameworks that I found in doing my research and hands-on experimenting.

Speaking of experimenting, I have published the Spring Boot GraphQL API that I made using graphql-spring-boot on Github, if you’re interested. Perhaps if there is any interest and if I find the time, I will post another article explaining that app in a tutorial format.

Now that you’ve read a bit more about GraphQL, it might be worth checking out our previous post, Is GraphQL Right for My Project?

The post Building a GraphQL Server with Java appeared first on Big Nerd Ranch.

]]>
Is GraphQL Right for My Project? https://bignerdranch.com/blog/is-graphql-right-for-my-project/ Mon, 16 Nov 2020 15:49:01 +0000 https://www.bignerdranch.com/?p=4607 Before you decide to make GraphQL a part of your own project there are a few key things to consider. To better understand the benefits and drawbacks that might sway your decision to use GraphQL let's discuss needs around performance, the various consumers of your application’s API’s, and the experience and buy in of your development team.

The post Is GraphQL Right for My Project? appeared first on Big Nerd Ranch.

]]>
By now you’ve probably heard the buzz around GraphQL. If you haven’t, check out the first post in our series, What is GraphQL? to get a basic understanding.

Proponents of GraphQL will tell stories of API consumers asking for exactly the data they need and getting it back in a concise package, formatted exactly as expected, and lightning-fast to boot. You’ve probably heard about queries and evolving schemas that make it easier to iterate over time and remove the headaches of deprecated endpoints that result from more typical patterns of versioning. These things are all great, but before you decide to make GraphQL a part of your own project there are a few key things to consider.

To better understand the benefits and drawbacks that might sway your decision to use GraphQL let’s discuss needs around performance, the various consumers of your application’s APIs, and the experience and buy-in of your development team.

Performance

One of the most important reasons you might consider adopting GraphQL is performance. Problems such as over-fetching of data or applications requiring multiple network requests to load can be easily addressed once your application is using GraphQL. A great example is Facebook.

The social media giant found itself grappling with the first of those issues in 2012. Adding new users to the platform was a top priority for the company, and most of those potential new users were located in areas that lacked faster internet access. Because of these slower networks, Facebook needed to cut down on the load times for their web pages. If all that was required to load a webpage was a user’s full name and email address, there was no reason to fetch all the information available on a user. When Facebook began using GraphQL, developers were able to write applications that only requested the information they needed to load, thereby decreasing page load times and improving overall application performance.

Of course, not all applications suffer a serious performance hit because of over-fetching data. Many applications do require multiple requests to load a single webpage, and in that area of performance improvement, GraphQL can still be helpful.

Consider a typical microservices architecture where you have a number of services managing different parts of your application’s data. Maintainability is made easier by separation of concerns, but your application is slow because every page of your website requires multiple HTTP requests to load. This was the case for Expedia Group. Implementing GraphQL allowed Expedia’s web pages to request everything necessary to load by hitting a single endpoint. This increased performance by decreasing the number of round trips necessary to gather the data needed by their application and simplified the developer experience by unifying the needed information under a single endpoint.

Architecture

Some more considerations when looking to GraphQL are the differing needs and the number of clients that will utilize your APIs. Native and web applications will most likely request data from your API’s in different ways and in different quantities. So it’s important to consider all the information that might be consumed by both internal and external users of Github’s API, for example.

One client might only need a small fraction of the information in the GitHub data graph because they are building a widget to visualize a commit history. Another client might need all of the available data because they are building their own native GitHub client. Using GraphQL, developers can build applications that request the data they need without requiring the server-side team to make changes to the API.

In addition, as the needs of each of the applications change as new consumers of your API arise, it’s possible that you will not need to make any changes to your GraphQL schema or your server-side code. This doesn’t mean that certain fields can’t be restricted or that your GraphQL schema can’t evolve over time. It just reduces the likelihood that changes will need to be made when compared to a more traditional set of REST-ful services.

Team

So far you have heard about technical considerations when deciding whether or not to use GraphQL, but the composition and experience of your development team are also critical in making the decision. Unlike front-end component libraries such as React and server-side frameworks like Rails, adopting GraphQL will have dramatic effects on both sides of your tech stack.

GraphQL moves control over what is fetched from your API away from the back-end team and more to the front-end team working on your application. This might free up time for your back-end team once GraphQL is implemented, but it’s important to consider whether or not your front-end team has the time to make the code changes necessary to take advantage of GraphQL. It’s also important to remember that your back-end team will shoulder some additional level of responsibility when adding GraphQL to your tech stack since GraphQL needs to be added to your API before your applications can take advantage of it.

The expertise of your team should come into play as well. Is anyone on your team experienced with GraphQL? Are they willing to help other developers learn the technology? Are the inexperienced developers on your team willing to learn GraphQL and can you give them the time to do so? For these reasons, it’s also critical to make sure you have the buy-in of your entire development team before making GraphQL a part of your application.

Summary

Deciding whether or not to adopt a tool like GraphQL has huge implications for how you and your team will go about building out a new application or reworking an existing one. A broad range of clients consuming your API’s, many complex data structures spread across a microservices architecture, and performance needs that are critical to the success of your business are a few good places to start.

But they aren’t the only things to consider—developer experience, maintainability of the application, and willingness to adopt newer technology and the rapid changes that accompany that decision are also key factors in determining whether or not GraphQL is the right choice for your project. And since adopting GraphQL will affect both the back-end and front-end of your tech stack, it is critical that you have the full buy-in of your entire development team.

In the coming posts, we’ll explore how GraphQL compares with more traditional REST architecture and share some things to try before deciding you want to use GraphQL.

The post Is GraphQL Right for My Project? appeared first on Big Nerd Ranch.

]]>
What is GraphQL? https://bignerdranch.com/blog/what-is-graphql/ Fri, 06 Nov 2020 16:13:44 +0000 https://www.bignerdranch.com/?p=4604 GraphQL can revolutionize your product by improving performance, reducing friction between development teams, and even helping with documentation. But it's important to understand the tool before deciding that it is the right one for the job.

The post What is GraphQL? appeared first on Big Nerd Ranch.

]]>
GraphQL can revolutionize your product by improving performance, reducing friction between development teams, and even helping with documentation. But it’s important to understand the tool before deciding if it’s the right one for the job. This is the first post in a series that intends to give a strong foundational knowledge to anyone interested in learning if GraphQL is right for their project.

Defining GraphQL

First, let’s explore the basics of GraphQL in order to get a baseline understanding of this query language.

We’ll start with a definition. According to the GraphQL Foundation,  “GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data.”

At its core, GraphQL allows the client to retrieve data from the server. It is a specification that can have different implementations for different platforms, on both the client and server-side. GraphQL also contains a key defining feature that makes it stand out from other web services, which we will explore next.

Once the GraphQL architecture has been set up, the client only has to work with one endpoint, which is typically /graphql. By using this single endpoint, the client can request only the data it needs within the GraphQL query. This enormous degree of flexibility is what sets GraphQL apart because it lets the client control what data it receives. See below for a quick example taken from GraphQL.org:

What the client asks for:

{
    hero {
        name
        height
        mass
    }
}

In its simplest form, this is how the request would look in a POST request body being sent to /graphql:

{
  "query": "hero{name height mass}"
}

And this is what the client would receive:

{
    "hero": {
        "name": "Luke Skywalker",
        "height": 1.72,
        "mass": 77
    }
}

If the above scenario took place in a REST architecture, it is easy to imagine that the client could have asked for the hero and received a lot of unneeded data (over-fetching), or the client may have had to make multiple calls to receive each of these specific attributes (under-fetching). Thanks to GraphQL, we have the advantage of “exactly-right fetching.”

There is much more to GraphQL and its advantages (and disadvantages), but before we get there, let’s briefly explore its origins.

GraphQL History

In 2012, Facebook began its efforts to redesign its native mobile apps due to their poor performance. This effort created new consumers of all their APIs and complex data. Additionally, performance became more critical as large user bases began to grow in regions of the world that lacked fast cellular networks. Milliseconds and kilobytes now mattered more than ever when fetching data.

Unfortunately, this redesign led to frustration. Not only did Facebook have to grapple with the difference between the data they wanted to use and the server queries required to fetch them, but they also had to write a considerable amount of code on both the server and client-side to prepare and parse the data.

These struggles led Facebook to rethink mobile app data-fetching from the perspective of product designers and developers. What was started as an internal project to give more control to the client-side grew into what is now known as GraphQL.

In 2015, it was made open-source. Then, in 2018, the GraphQL project was moved from Facebook to the GraphQL Foundation which is hosted by the non-profit Linux Foundation. A large community of developers and technology companies has grown around it ever since to provide contributions and stewardship to GraphQL.

GraphQL Adopters

Since becoming open-source, a variety of companies have adopted GraphQL. Some of the most recognizable names are:

  • Pinterest
  • Shopify
  • AirBnB
  • PayPal

As you can see, if you choose to implement GraphQL, you will be in good company. According to GraphQL, their users have a combined market cap of $4.08T and funding of $9.34B. For a more complete list of big-name adopters, take a look at this landscape.

Which Team Members Should Be Interested in GraphQL?

Interest in GraphQL can come from several different roles in your organization.

Front-end developers might be interested in implementing it to reduce the number of requests they need to make. Or they might be drawn in by the “exactly-right” fetching we discussed earlier. The front-end devs might also be attracted to the potential for fast iteration on their side. Without the need to ask the server-side to update an endpoint every time the UI changes, the front-end can make changes faster and with less friction.

On the back-end, developers can create a GraphQL server using any common language. This makes GraphQL a strong option to consider. A key reason back-end developers will be interested in GraphQL is that they will not have to spend time making changes to endpoints every time the front-end has changed. Not only this, but GraphQL could also replace legacy REST APIs and reduce the amount of versioning and maintenance required. Another upside for back-end developers is the self-documenting nature of the GraphQL schema.

Project stakeholders would also benefit from learning about GraphQL and what implementing it could mean for a project. If performance is critical, GraphQL would be something to give strong consideration to, especially for apps operating in areas with slower internet speeds. GraphQL could be a valid solution for a project that has growing technical debt due to legacy or ever-evolving REST APIs. A project that has complex systems and microservices could also benefit from the unification that GraphQL can provide.

Tooling & Resources

Due to the growing popularity of GraphQL, there are numerous tools and resources to help you get started.

  • Apollo – The industry-standard GraphQL implementation. According to their website, you can be up and running with a GraphQL data graph in about an hour.
  • GraphiQL – The IDE for GraphQL.
  • Postman – A popular platform for API development that supports GraphQL.
  • Paw – A Mac app that lets you test and describe the APIs you build or consume which now has support for GraphQL.
  • How To GraphQL – An in-depth, open-source tutorial to get GraphQL up and running.

Is GraphQL the Right Choice?

We’ve just begun to scratch the surface of GraphQL and what it can do for your project. But just like any other tool, considerations must be made to determine if it is the right one for the job.

For help in determining whether GraphQL is the right choice, be on the lookout for our next post: Is GraphQL Right For My Project?

The post What is GraphQL? appeared first on Big Nerd Ranch.

]]>