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.
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:
1
GraphQL Basics
Jane Smith
2
Learning GraphQL
John Doe
In this example, the library
contains multiple book
elements, each of which has an id
, title
, and author
.
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.
query {
book(id: 1) {
title
author
}
}
{
"data": {
"book": {
"title": "GraphQL Basics",
"author": "Jane Smith"
}
}
}
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.
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();
1
GraphQL Basics
Jane Smith
{
"library": {
"book": [
{
"id": ["1"],
"title": ["GraphQL Basics"],
"author": ["Jane Smith"]
}
]
}
}
This JSON
structure is now ready to be integrated into a GraphQL API.
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.
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;
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.
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;
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.
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.
query {
books {
id
title
author
}
}
{
"data": {
"books": [
{
"id": "1",
"title": "GraphQL Basics",
"author": "Jane Smith"
}
]
}
}
XML data can be deeply nested, and sometimes we need to expose nested structures via GraphQL.
1
GraphQL Advanced
John Doe
johndoe@example.com
type Author {
name: String!
email: String!
}
type Book {
id: ID!
title: String!
author: Author!
}
type Query {
books: [Book]
}
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
.
xml-stream
to process data incrementally, preventing memory overload.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 !❤️