
Product
Introducing Socket Firewall Enterprise: Flexible, Configurable Protection for Modern Package Ecosystems
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.
graphql-query-to-json
Advanced tools
Convert graphQL queries and mutations to easily readable JSON representations.
A TypeScript library that converts GraphQL query and mutation strings into structured JSON objects. This library serves as the reverse of json-to-graphql-query, enabling programmatic manipulation and analysis of GraphQL queries.
npm install graphql-query-to-json
# or
yarn add graphql-query-to-json
const {graphQlQueryToJson} = require("graphql-query-to-json")
const query = `
query GetThisStuff($name: String, $lastName: String) {
viewer {
personal(criteria: {
name: $name,
lastName: $lastName
}) {
name
address
}
}
}
`
const result = graphQlQueryToJson(query, {
variables: {
name: "PETER",
lastName: "SCHMIDT",
},
})
console.log(result)
// Output:
{
query: {
viewer: {
personal: {
__args: {
criteria: {
name: "PETER",
lastName: "SCHMIDT",
},
},
name: true,
address: true,
},
},
},
}
The library follows predictable transformation patterns:
| GraphQL Element | JSON Representation | Example |
|---|---|---|
| Scalar Fields | true | name → name: true |
| Object Fields | Nested objects | user { name } → user: { name: true } |
| Arguments | __args property | user(id: 1) → user: { __args: { id: 1 } } |
| Aliases | Field renaming + __aliasFor | renamed: user → renamed: { __aliasFor: "user" } |
| Variables | Substituted values | $userId → actual variable value |
| Enums | EnumType wrapper | status: ACTIVE → status: { "value": "ACTIVE" } |
| Inline Fragments | __on property | ... on User { name } → __on: { __typeName: "User", name: true } |
// Single and multiple fields
const query = `
query {
viewer {
name
email
}
user {
profile {
avatar
bio
}
}
}
`
const result = graphQlQueryToJson(query)
// Output:
{
query: {
viewer: {
name: true,
email: true
},
user: {
profile: {
avatar: true,
bio: true
}
}
}
}
// Query with variables
const query = `
query GetUser($userId: ID!, $includeProfile: Boolean!) {
user(id: $userId) {
name
email
profile @include(if: $includeProfile) {
bio
avatar
}
}
}
`
const result = graphQlQueryToJson(query, {
variables: {
userId: "123",
includeProfile: true
}
})
// Output:
{
query: {
user: {
__args: { id: "123" },
name: true,
email: true,
profile: {
bio: true,
avatar: true
}
}
}
}
// Scalar fields that accept arguments
const query = `
query {
userCount(filter: "active")
totalRevenue(currency: "USD", year: 2024)
averageRating(precision: 2)
}
`
const result = graphQlQueryToJson(query)
// Output:
{
query: {
userCount: {
__args: { filter: "active" }
},
totalRevenue: {
__args: { currency: "USD", year: 2024 }
},
averageRating: {
__args: { precision: 2 }
}
}
}
const mutation = `
mutation {
getPersonalStuff(name: "PETER") {
personal {
name
address
}
other {
parents
}
}
}
`
const result = graphQlQueryToJson(mutation)
// Output:
{
mutation: {
getPersonalStuff: {
__args: {
name: "PETER",
},
personal: {
name: true,
address: true,
},
other: {
parents: true,
},
},
},
}
// Mutation with nested object arguments
const mutation = `
mutation CreateUser($input: UserInput!) {
createUser(input: $input) {
id
name
profile {
email
settings {
theme
notifications
}
}
}
}
`
const result = graphQlQueryToJson(mutation, {
variables: {
input: {
name: "John Doe",
email: "john@example.com",
}
}
})
// Output:
{
mutation: {
createUser: {
__args: {
input: {
name: "John Doe",
email: "john@example.com"
}
},
id: true,
name: true,
profile: {
email: true,
settings: {
theme: true,
notifications: true
}
}
}
}
}
// Multiple aliases for the same field
const query = `
query {
currentUser: user(id: 1) {
name
email
}
adminUser: user(id: 2) {
name
permissions
}
guestUser: user(id: 3) {
name
status
}
}
`
const result = graphQlQueryToJson(query)
// Output:
{
query: {
currentUser: {
__aliasFor: "user",
__args: { id: 1 },
name: true,
email: true
},
adminUser: {
__aliasFor: "user",
__args: { id: 2 },
name: true,
permissions: true
},
guestUser: {
__aliasFor: "user",
__args: { id: 3 },
name: true,
status: true
}
}
}
// Enums in arguments
const query = `
query {
posts(status: PUBLISHED, orderBy: CREATED_DESC) {
title
content
}
users(role: ADMIN, sortBy: NAME_ASC) {
name
email
}
}
`
const result = graphQlQueryToJson(query)
// Output (enums are wrapped in EnumType objects):
{
query: {
posts: {
__args: {
status: { "value": "PUBLISHED" },
orderBy: { "value": "CREATED_DESC" }
},
title: true,
content: true
},
users: {
__args: {
role: { "value": "ADMIN" },
sortBy: { "value": "NAME_ASC" }
},
name: true,
email: true
}
}
}
// Lists and arrays as arguments
const mutation = `
mutation {
updateUser(
id: "123",
tags: ["developer", "typescript", "graphql"],
permissions: [READ, WRITE, ADMIN]
) {
id
tags
permissions
}
}
`
const result = graphQlQueryToJson(mutation)
// Output:
{
mutation: {
updateUser: {
__args: {
id: "123",
tags: ["developer", "typescript", "graphql"],
permissions: [
"READ",
"WRITE",
"ADMIN"
]
},
id: true,
tags: true,
permissions: true
}
}
}
// Empty strings, objects, and arrays
const mutation = `
mutation {
createRecord(input: {
name: "",
metadata: {},
tags: [],
count: 0,
isActive: false
}) {
id
status
}
}
`
const result = graphQlQueryToJson(mutation)
// Output:
{
mutation: {
createRecord: {
__args: {
input: {
name: "",
metadata: {},
tags: [],
count: 0,
isActive: false
}
},
id: true,
status: true
}
}
}
// Complex nested structures
const query = `
query {
organization {
teams {
members {
user {
profile {
personalInfo {
address {
street
city
country
}
}
}
}
}
}
}
}
`
const result = graphQlQueryToJson(query)
// Output:
{
query: {
organization: {
teams: {
members: {
user: {
profile: {
personalInfo: {
address: {
street: true,
city: true,
country: true
}
}
}
}
}
}
}
}
}
// Float arguments and numeric types
const query = `
query GetProducts {
products(
minRating: 4.5,
maxPrice: 99.99,
discount: -10.5,
threshold: 0.001,
scientific: 2.5e3
) {
name
rating
price
}
analytics(
coordinates: {
lat: 40.7128,
lng: -74.006
},
mixed: [1, 2.5, 3, 4.75]
) {
data
}
}
`
const result = graphQlQueryToJson(query)
// Output:
{
query: {
products: {
__args: {
minRating: 4.5, // âś… Float as number
maxPrice: 99.99, // âś… Float as number
discount: -10.5, // âś… Negative float
threshold: 0.001, // âś… Small decimal
scientific: 2500 // âś… Scientific notation (2.5e3)
},
name: true,
rating: true,
price: true
},
analytics: {
__args: {
coordinates: {
lat: 40.7128, // âś… Nested floats
lng: -74.006
},
mixed: ["1", "2.5", "3", "4.75"] // Arrays preserve strings
},
data: true
}
}
}
// Single inline fragment
const query = `
query {
posts {
title
... on TextPost {
content
wordCount
}
}
}
`
const result = graphQlQueryToJson(query)
// Output:
{
query: {
posts: {
title: true,
__on: {
__typeName: "TextPost",
content: true,
wordCount: true
}
}
}
}
// Multiple inline fragments
const query = `
query {
media {
... on TextPost {
content
author {
name
}
}
... on ImagePost {
imageUrl
altText
}
... on VideoPost {
videoUrl
duration
}
}
}
`
const result = graphQlQueryToJson(query)
// Output:
{
query: {
media: {
__on: [
{
__typeName: "TextPost",
content: true,
author: {
name: true
}
},
{
__typeName: "ImagePost",
imageUrl: true,
altText: true
},
{
__typeName: "VideoPost",
videoUrl: true,
duration: true
}
]
}
}
}
// Inline fragments with arguments and variables
const query = `
query GetPosts($limit: Int!) {
posts {
title
... on TextPost {
comments(limit: $limit) {
text
author {
name
}
}
}
}
}
`
const result = graphQlQueryToJson(query, {
variables: { limit: 5 }
})
// Output:
{
query: {
posts: {
title: true,
__on: {
__typeName: "TextPost",
comments: {
__args: { limit: 5 },
text: true,
author: {
name: true
}
}
}
}
}
}
// Basic subscription
const subscription = `
subscription {
messageAdded {
id
content
user {
name
email
}
}
}
`
const result = graphQlQueryToJson(subscription)
// Output:
{
subscription: {
messageAdded: {
id: true,
content: true,
user: {
name: true,
email: true
}
}
}
}
// Subscription with variables and arguments
const subscription = `
subscription MessageSubscription($userId: ID!, $channel: String!) {
messageAdded(userId: $userId, channel: $channel) {
id
content
timestamp
}
}
`
const result = graphQlQueryToJson(subscription, {
variables: {
userId: "123",
channel: "general"
}
})
// Output:
{
subscription: {
messageAdded: {
__args: {
userId: "123",
channel: "general"
},
id: true,
content: true,
timestamp: true
}
}
}
// Subscription with aliases and enums
const subscription = `
subscription {
latestMessage: messageAdded(channel: PUBLIC) {
id
content
}
}
`
const result = graphQlQueryToJson(subscription)
// Output:
{
subscription: {
latestMessage: {
__aliasFor: "messageAdded",
__args: {
channel: { "value": "PUBLIC" }
},
id: true,
content: true
}
}
}
graphQlQueryToJson(query, options?)Parameters:
query (string): The GraphQL query, mutation, or subscription stringoptions (object, optional):
variables (object): Variables referenced in the queryReturns: JSON object representation of the GraphQL query
Throws:
While the library supports the core GraphQL features, there are some limitations:
... on TypeName)// ❌ Named fragments still throw an error
const queryWithFragment = `
query {
user {
...UserFields
}
}
fragment UserFields on User {
id
name
}
`
// Throws: "The parsed query has more than one set of definitions"
// âś… Inline fragments work perfectly
const queryWithInlineFragment = `
query {
search {
... on User {
name
}
... on Post {
title
}
}
}
`
// Output: { query: { search: { __on: [...] } } }
@include, @skip are parsed but ignored// âś… This works but directives are ignored
const queryWithDirective = `
query($includeEmail: Boolean!) {
user {
name
email @include(if: $includeEmail)
}
}
`
// The @include directive won't affect the output structure
These limitations apply equally to queries, mutations, and subscriptions since they all use the same AST processing logic.
Full TypeScript definitions are included:
import { graphQlQueryToJson } from 'graphql-query-to-json'
interface Variables {
userId: string
limit: number
}
const variables: Variables = {
userId: "123",
limit: 10
}
const result = graphQlQueryToJson(query, { variables })
// Result is properly typed
npm run build # Compile TypeScript to JavaScript
npm run watch # Build in watch mode
npm test # Run Jest tests
npm run test:coverage # Run tests with coverage
npm run lintFull # Run Prettier and ESLint with auto-fix
The library uses a multi-phase approach:
graphql library to parse query into ASTKey components:
getSelections(): Processes field selections recursivelygetArguments(): Handles all argument types and nestingreplaceVariables(): Deep variable substitution using lodash.mapValuescheckEachVariableInQueryIsDefined(): Variable validation with descriptive errorsnpm run build && npm testMIT License - see LICENSE file for details
FAQs
Convert graphQL queries and mutations to easily readable JSON representations.
We found that graphql-query-to-json demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.

Security News
Open source dashboard CNAPulse tracks CVE Numbering Authorities’ publishing activity, highlighting trends and transparency across the CVE ecosystem.

Product
Detect malware, unsafe data flows, and license issues in GitHub Actions with Socket’s new workflow scanning support.