Integrating XML with GraphQL APIs

In today’s development world, XML (eXtensible Markup Language) is still widely used for data storage and transfer, especially in legacy systems. However, modern applications demand flexible and efficient ways to access and manipulate this data. This is where GraphQL comes into play. GraphQL is a query language for APIs that allows clients to request only the data they need, simplifying the way we interact with data. Integrating XML with GraphQL APIs enables you to expose XML data in a more flexible, efficient, and client-friendly manner.In this chapter, we will explore the full process of integrating XML data into a GraphQL API, covering everything from the basics of GraphQL to detailed examples and advanced use cases.

Basics of XML and GraphQL

What is XML?

XML is a markup language that defines rules for encoding documents in a format that is both human-readable and machine-readable. It uses tags to organize data hierarchically, which makes it versatile for storing complex structured data.

Example XML:

				
					<library>
    <book>
        <id>1</id>
        <title>GraphQL Basics</title>
        <author>Jane Smith</author>
    </book>
    <book>
        <id>2</id>
        <title>Learning GraphQL</title>
        <author>John Doe</author>
    </book>
</library>

				
			

In this example, the library contains multiple book elements, each of which has an id, title, and author.

What is GraphQL?

GraphQL is a query language that provides an efficient and flexible way to request data. Unlike REST APIs, where the client must make multiple requests for different pieces of data, GraphQL allows clients to specify exactly what they need in a single request.

Key Features of GraphQL:

  • Single Endpoint: One URL for all queries.
  • Typed Schema: Clients know exactly what data to expect.
  • Selective Fetching: Clients fetch only the data they need.

Example GraphQL Query:

				
					query {
  book(id: 1) {
    title
    author
  }
}

				
			

Response

				
					{
  "data": {
    "book": {
      "title": "GraphQL Basics",
      "author": "Jane Smith"
    }
  }
}

				
			

How to Integrate XML with GraphQL

Step 1: Parse XML Data

The first step in integrating XML with GraphQL is parsing the XML data into a format that GraphQL can work with, typically JSON. This can be done using libraries such as xml2js in Node.js.

Example Code to Parse XML:

				
					const fs = require('fs');
const { parseStringPromise } = require('xml2js');

// Function to parse XML file into JSON
async function parseXML() {
  const xmlData = fs.readFileSync('library.xml', 'utf-8');
  const jsonData = await parseStringPromise(xmlData);
  console.log(jsonData);
}

parseXML();

				
			

Input (library.xml):

				
					<library>
  <book>
    <id>1</id>
    <title>GraphQL Basics</title>
    <author>Jane Smith</author>
  </book>
</library>

				
			

Output (JSON):

				
					{
  "library": {
    "book": [
      {
        "id": ["1"],
        "title": ["GraphQL Basics"],
        "author": ["Jane Smith"]
      }
    ]
  }
}

				
			

This JSON structure is now ready to be integrated into a GraphQL API.

Define GraphQL Schema

In GraphQL, you define a schema that specifies the types of data available and how clients can query that data. Here, we will define a simple schema to expose books stored in XML.

GraphQL Schema Example:

				
					const { gql } = require('apollo-server');

// Define types for Book and Query
const typeDefs = gql`
  type Book {
    id: ID!
    title: String!
    author: String!
  }

  type Query {
    books: [Book]
    book(id: ID!): Book
  }
`;

module.exports = typeDefs;

				
			

Create Resolvers

Resolvers map GraphQL queries to backend data, which in our case is the XML data (converted to JSON). In this step, we will create resolvers to fetch books and individual book details.

GraphQL Resolver Example:

				
					const fs = require('fs');
const { parseStringPromise } = require('xml2js');

const resolvers = {
  Query: {
    // Get all books
    books: async () => {
      const xmlData = fs.readFileSync('library.xml', 'utf-8');
      const jsonData = await parseStringPromise(xmlData);
      return jsonData.library.book.map(book => ({
        id: book.id[0],
        title: book.title[0],
        author: book.author[0]
      }));
    },
    // Get a specific book by ID
    book: async (_, { id }) => {
      const xmlData = fs.readFileSync('library.xml', 'utf-8');
      const jsonData = await parseStringPromise(xmlData);
      const book = jsonData.library.book.find(b => b.id[0] === id);
      if (!book) {
        throw new Error("Book not found");
      }
      return {
        id: book.id[0],
        title: book.title[0],
        author: book.author[0]
      };
    }
  }
};

module.exports = resolvers;

				
			

Set Up the GraphQL Server

To expose the XML data through GraphQL, we need to set up a GraphQL server. We’ll use Apollo Server, which is a popular JavaScript GraphQL server.

GraphQL Server Setup Example:

				
					const { ApolloServer } = require('apollo-server');
const typeDefs = require('./schema');
const resolvers = require('./resolvers');

// Initialize Apollo Server
const server = new ApolloServer({ typeDefs, resolvers });

// Start the server
server.listen().then(({ url }) => {
  console.log(`Server ready at ${url}`);
});

				
			

Once the server is running, you can access GraphQL Playground or any GraphQL client to test your API.

GraphQL Query Example:

				
					query {
  books {
    id
    title
    author
  }
}

				
			

Response:

				
					{
  "data": {
    "books": [
      {
        "id": "1",
        "title": "GraphQL Basics",
        "author": "Jane Smith"
      }
    ]
  }
}

				
			

Advanced Use Cases

Handling Nested XML Structures

XML data can be deeply nested, and sometimes we need to expose nested structures via GraphQL.

Example XML with Nested Data:

				
					<library>
  <book>
    <id>1</id>
    <title>GraphQL Advanced</title>
    <author>
      <name>John Doe</name>
      <email>johndoe@example.com</email>
    </author>
  </book>
</library>

				
			

GraphQL Schema for Nested Data

				
					type Author {
  name: String!
  email: String!
}

type Book {
  id: ID!
  title: String!
  author: Author!
}

type Query {
  books: [Book]
}

				
			

GraphQL Resolver for Nested Data:

				
					const resolvers = {
  Query: {
    books: async () => {
      const xmlData = fs.readFileSync('library.xml', 'utf-8');
      const jsonData = await parseStringPromise(xmlData);
      return jsonData.library.book.map(book => ({
        id: book.id[0],
        title: book.title[0],
        author: {
          name: book.author[0].name[0],
          email: book.author[0].email[0]
        }
      }));
    }
  }
};

				
			

This setup enables us to query deeply nested data like author.name and author.email.

Best Practices

  • Efficient Parsing: Cache parsed XML to prevent repeated parsing operations.
  • Error Handling: Handle errors in resolvers gracefully, especially when querying deeply nested data or when XML data is malformed.
  • Scalability: For large XML datasets, consider using streaming parsers like xml-stream to process data incrementally, preventing memory overload.
  • Data Transformation: If XML data requires significant transformation before being exposed, use utility functions to map XML elements to GraphQL types.

Integrating XML with GraphQL APIs offers a powerful way to modernize systems that rely on XML while taking advantage of GraphQL's flexibility and efficiency. This chapter provided a step-by-step guide to parsing XML, defining GraphQL schemas, creating resolvers, and setting up a GraphQL server. By following these steps, developers can expose legacy XML data through modern GraphQL APIs, making it easier to access, query, and manage XML-based information in today’s applications. Happy coding !❤️

Table of Contents

Contact here

Copyright © 2025 Diginode

Made with ❤️ in India