Create a GraphQL Mesh from scratch

Create a GraphQL Mesh from scratch

GraphQL Mesh is a powerful tool that allows you to use GraphQL query language, regardless of the source’s original format. It can be used with REST APIs, gRPC, SOAP, and more. In this blog post, we’ll explore how to set up and use GraphQL Mesh in your projects.

Warning: The article requires a bit of NodeJS knowledge. The examples are tested with NodeJS 16.
We also define a environment variable MAGENTO_ACCESS_TOKEN containing a a Magento Bearer Token. to access the API. If you don’t have a Magento system available the then replace it with another GraphQL endpoint and modify the examples here.

Setting Up GraphQL Mesh

To get started with GraphQL Mesh, you’ll first need to install the necessary dependencies. You can do this by adding the following to your package.json file:

{
  "dependencies": {
    "@graphql-mesh/cli": "^0.82.35",
    "@graphql-mesh/graphql": "^0.22.7",
    "@graphql-mesh/openapi": "^0.24.13",
    "@graphql-mesh/transform-filter-schema": "^0.14.115",
    "@graphql-mesh/transform-prefix": "^0.93.1",
    "graphql": "^16.6.0"
  }
}

Once you’ve added these dependencies, you can install them using your package manager of choice.

Install the dependencies with yarn or npm. We use yarn here:

yarn install

Writing a GraphQL Query

With GraphQL Mesh, you can write queries that fetch data from multiple sources. Here’s an example of a GraphQL query that fetches product data and station data (yes, it’s a wild mix of APIs):

{
  products(currentPage: 1, pageSize: 3, search:"24-MB01") {
    items {
      sku
      ... on SimpleProduct {
        my_calculated_price
      }
      price_range {
        minimum_price {
          final_price {
            currency
            value
          }
        }        
      }
    }
  }
  continents {
    code
  }
}

In this example, products and continents are two different queries that fetch data from different sources. The products query fetches product data, while continents fetches geographical information. Both queries are fired agains two different backend systems and APIs. As a developer you don’t see the backend systems. You see only one unified APIs. That’s one of the big advantages.

Creating Resolvers

Resolvers in GraphQL are functions that resolve data for your queries. In GraphQL Mesh, you can create resolvers that fetch data from your sources and return it in the format you need. Here’s an example of a resolver for the SimpleProduct type:

import { Resolvers } from './.mesh'

const resolvers: Resolvers = {
    SimpleProduct: {
        my_calculated_price: {
            selectionSet: /* GraphQL */`
            {
                id,
                price_range {
                    minimum_price {
                        final_price {
                            value
                        }
                    }        
                }
            }
            `,
            resolve: async (root, _args, context, info) => {
                console.log(root)
                return (99.98 + root.price_range.minimum_price.final_price.value).toFixed(4)
            }
        }
    }
}

export default resolvers

In this example, the my_calculated_price resolver fetches the price of a product and adds a fixed amount to it as example of a price calculation. We added a console.log here. If you query the products with the my_calculated_price field then you should see the value in your running console.

Configuring GraphQL Mesh

Finally, you’ll need to configure GraphQL Mesh to use your sources and resolvers. You can do this in the .meshrc.yaml file:

serve:
  port: 5000
  browser: false
  playground: true
sources:
  - name: Magento
    handler:
      graphql:
        endpoint: https://magento-demo.example.com/graphql
        operationHeaders:
          Authorization: Bearer {env.MAGENTO_ACCESS_TOKEN}

  - name: Countries
    handler:
      graphql:
        endpoint: https://countries.trevorblades.com

transforms:
  - filterSchema:
      mode: wrap
      filters:
        - Query.!giftCardAccount

additionalTypeDefs: |
  extend type SimpleProduct {


    sap_price: Float
  }


additionalResolvers:
    - "./resolvers"

In this configuration file, we’ve defined two sources: Magento and Countries. Each source has a GraphQL endpoint that GraphQL Mesh will fetch data from. We’ve also defined a transform that filters out the giftCardAccount query from the schema.

The additionalTypeDefs section allows us to extend existing types with our own fields. In this case, we’re extending the SimpleProduct type with a my_calculated_price field.

The additionalResolvers section is where we specify the path to our resolvers file.

The library can do a lot of more stuff. One important feature is filtering the schema. Sometimes you don’t want publish everything in your schema. We then use a filter transformer to strip some meta data (giftCardAccount query in our example). It’s then not possible anymore to fetch this entities.

You can find a brief documentation here: https://the-guild.dev/graphql/mesh

Now you can try to run the mesh:

yarn mesh build
yarn mesh start
// or dev mode -> yarn mesh dev

This should build and run the mesh.

If you open the printed url in your browser you should see a nice API playground.

Conclusion

GraphQL Mesh is a powerful tool that allows you to use GraphQL with any source, regardless of its original format. By setting up your dependencies, writing your queries, creating your resolvers, and configuring GraphQL Mesh, you can start fetching data from multiple sources with ease.

Remember, the examples provided in this blog post are just that – examples. Your actual implementation may vary based on your specific needs and the sources you’re working with. However, these examples should provide a solid foundation for you to start working with GraphQL Mesh. Happy coding!

Leave a Reply

Your email address will not be published. Required fields are marked *