Skip to main content

Features

Page 3.3.1: GraphQL Schema Details

Introduction

The GraphQL schema defines the types, queries, mutations, and subscriptions available in the API. Understanding the schema is crucial for effective interaction with the API.


Subsection 3.3.1.1: Types

Page 3.3.1.1.1: Node Type
Definition

The Node type represents an item or category in the inventory system.

type Node {
  id: ID!
  title: String!
  data: JSON
  parent: Node
  children: [Node!]
}
Fields
  • id (ID!): The unique identifier of the node.
  • title (String!): The name of the node.
  • data (JSON): Additional data associated with the node in JSON format.
  • parent (Node): The parent node.
  • children ([Node!]): A list of child nodes.
Description
  • id: Automatically generated UUID for the node.
  • title: Should be descriptive and unique within its parent context.
  • data: Can store custom JSON data relevant to the node.
  • parent: Allows traversal up the node hierarchy.
  • children: Enables traversal down the node hierarchy.

Page 3.3.1.1.2: User Type
Definition

The User type represents a user account in the system.

type User {
  id: ID!
  username: String!
  isAdmin: Boolean!
}
Fields
  • id (ID!): The unique identifier of the user.
  • username (String!): The user's login name.
  • isAdmin (Boolean!): Indicates if the user has administrative privileges.
Description
  • id: Automatically generated UUID for the user.
  • username: Must be unique across the system.
  • isAdmin: true for administrators, false for regular users.

Subsection 3.3.1.2: Queries

Page 3.3.1.2.1: Get Node
Purpose

Retrieve a specific node by its ID, including its details and relationships.

Query Definition
query getNode($id: ID!) {
  node(id: $id) {
    id
    title
    data
    parent {
      id
      title
    }
    children {
      id
      title
    }
  }
}
Parameters
  • id (ID!): The unique identifier of the node to retrieve.
Example Usage

Request Variables:

{
  "id": "123e4567-e89b-12d3-a456-426614174000"
}

Response:

{
  "data": {
    "node": {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "title": "Electronics",
      "data": null,
      "parent": null,
      "children": [
        {
          "id": "223e4567-e89b-12d3-a456-426614174001",
          "title": "Computers"
        }
      ]
    }
  }
}
Notes
  • If the node does not exist or the user lacks permissions, node will be null.
  • You can customize the fields returned by adjusting the selection set.

Page 3.3.1.2.2: List Nodes
Purpose

Retrieve a list of all nodes or nodes matching specific criteria.

Query Definition
query listNodes($parentId: ID) {
  nodes(parentId: $parentId) {
    id
    title
    data
  }
}

 Parameters

  • parentId (ID): (Optional) Filter nodes that are direct children of the specified parent node.
Example Usage

Request Variables:

{
  "parentId": "123e4567-e89b-12d3-a456-426614174000"
}

Response:

{
  "data": {
    "nodes": [
      {
        "id": "223e4567-e89b-12d3-a456-426614174001",
        "title": "Computers",
        "data": null
      },
      {
        "id": "323e4567-e89b-12d3-a456-426614174002",
        "title": "Smartphones",
        "data": null
      }
    ]
  }
}
Notes
  • If parentId is omitted, all nodes in the system will be returned.
  • For large datasets, consider implementing pagination (if supported).

Subsection 3.3.1.3: Mutations

Page 3.3.1.3.1: Create Node
Purpose

Create a new node in the inventory system under a specified parent.

Mutation Definition
mutation createNode($input: CreateNodeInput!) {
  createNode(input: $input) {
    id
    title
    parent {
      id
      title
    }
  }
}

Input Type:

input CreateNodeInput {
  title: String!
  parentId: ID
  data: JSON
}
Parameters
  • input (CreateNodeInput!): The details of the node to create.
Example Usage

Request Variables:

{
  "input": {
    "title": "Laptops",
    "parentId": "223e4567-e89b-12d3-a456-426614174001",
    "data": null
  }
}

Response:

{
  "data": {
    "createNode": {
      "id": "423e4567-e89b-12d3-a456-426614174003",
      "title": "Laptops",
      "parent": {
        "id": "223e4567-e89b-12d3-a456-426614174001",
        "title": "Computers"
      }
    }
  }
}
Notes
  • parentId: If omitted, the node will be created at the root level.
  • Authentication: Requires a valid session token or cookie.
  • Permissions: The user must have permission to create nodes under the specified parent.

Page 3.3.1.3.2: Delete Node
Purpose

Delete an existing node and handle its child nodes according to the specified option.

Mutation Definition
mutation deleteNode($id: ID!, $option: DeleteOption!) {
  deleteNode(id: $id, option: $option) {
    success
    message
  }
}

Enum Type:

enum DeleteOption {
  DELETE_CHILDREN
  DUMP_CHILDREN
  RELOCATE_CHILDREN
}
Parameters
  • id (ID!): The unique identifier of the node to delete.

  • option (DeleteOption!): Determines how to handle child nodes.

    • DELETE_CHILDREN: Remove all child nodes along with the node.
    • DUMP_CHILDREN: Move child nodes up one level.
    • RELOCATE_CHILDREN: Requires an additional parameter to specify the new parent.
Example Usage

Request Variables:

{
  "id": "423e4567-e89b-12d3-a456-426614174003",
  "option": "DUMP_CHILDREN"
}

Response:

{
  "data": {
    "deleteNode": {
      "success": true,
      "message": "Node deleted and children dumped to parent level."
    }
  }
}
Notes
  • RELOCATE_CHILDREN: If this option is selected, you must provide the new parent ID.
  • Permissions: Only users with delete permissions can perform this action.
  • Irreversible: Deleting nodes is permanent; use with caution.

Page 3.3.1.3.3: Move Node
Purpose

Move a node to a new parent within the inventory hierarchy.

Mutation Definition
Notes
  • RELOCATE_CHILDREN: If this option is selected, you must provide the new parent ID.
  • Permissions: Only users with delete permissions can perform this action.
  • Irreversible: Deleting nodes is permanent; use with caution.

Page 3.3.1.3.3: Move Node
Purpose

Move a node to a new parent within the inventory hierarchy.

Mutation Definition
mutation moveNode($id: ID!, $newParentId: ID!) {
  moveNode(id: $id, newParentId: $newParentId) {
    id
    title
    parent {
      id
      title
    }
  }
}
 
Parameters
  • id (ID!): The unique identifier of the node to move.
  • newParentId (ID!): The unique identifier of the new parent node.
Example Usage

Request Variables:

{
  "id": "423e4567-e89b-12d3-a456-426614174003",
  "newParentId": "323e4567-e89b-12d3-a456-426614174002"
}

 

Response:

{
  "data": {
    "moveNode": {
      "id": "423e4567-e89b-12d3-a456-426614174003",
      "title": "Laptops",
      "parent": {
        "id": "323e4567-e89b-12d3-a456-426614174002",
        "title": "Smartphones"
      }
    }
  }
}

 

Notes

  • Circular References: The API prevents moving a node under one of its descendants.
  • Permissions: User must have permission to modify both the source and destination nodes.

Page 3.3.1.3.4: User Management (Admin Only)
Purpose

Administrative mutations for managing user accounts, such as creating or deleting users.

Mutation Definitions

Create User

mutation createUser($input: CreateUserInput!) {
  createUser(input: $input) {
    id
    username
    isAdmin
  }
}

 

Input Type:

input CreateUserInput {
  username: String!
  password: String!
  isAdmin: Boolean
}

 

Delete User

mutation deleteUser($id: ID!) {
  deleteUser(id: $id) {
    success
    message
  }
}

 

Parameters

  • Create User

    • input (CreateUserInput!): User details.
  • Delete User

    • id (ID!): Unique identifier of the user to delete.
Example Usage

Create User Variables:

{
  "input": {
    "username": "newuser",
    "password": "SecurePass123!",
    "isAdmin": false
  }
}

 

Create User Response:

{
  "data": {
    "createUser": {
      "id": "523e4567-e89b-12d3-a456-426614174004",
      "username": "newuser",
      "isAdmin": false
    }
  }
}

 

Delete User Variables:

{
  "id": "523e4567-e89b-12d3-a456-426614174004"
}

 

Delete User Response:

{
  "data": {
    "deleteUser": {
      "success": true,
      "message": "User deleted successfully."
    }
  }
}

 

Notes

  • Authentication: Only administrators can perform these mutations.
  • Password Security: Passwords are stored securely using hashing algorithms.

Subsection 3.3.1.4: Subscriptions

Page 3.3.1.4.1: Node Updates
Purpose

Subscribe to real-time updates when nodes are added, updated, or deleted.

Subscription Definition
subscription onNodeUpdated {
  nodeUpdated {
    event
    node {
      id
      title
      data
      parent {
        id
        title
      }
    }
  }
}
 
Fields
  • event (String!): The type of event (CREATED, UPDATED, DELETED).
  • node (Node): The node data related to the event.
Example Usage

Subscription:

subscription {
  nodeUpdated {
    event
    node {
      id
      title
      parent {
        id
        title
      }
    }
  }
}

Real-Time Updates:

  • Event: A new node is created.

Received Data:

{
  "data": {
    "nodeUpdated": {
      "event": "CREATED",
      "node": {
        "id": "623e4567-e89b-12d3-a456-426614174005",
        "title": "Tablets",
        "parent": {
          "id": "223e4567-e89b-12d3-a456-426614174001",
          "title": "Computers"
        }
      }
    }
  }
}

Notes

  • WebSocket Connection: Subscriptions require a WebSocket connection.
  • Authentication: Ensure the client is authenticated if required.

Page 3.3.2: Interactive Playground

Introduction

The interactive playground is a powerful tool that allows you to test and execute GraphQL queries, mutations, and subscriptions directly from your browser.

Accessing the Playground

  • URL: http://127.0.0.1/docs

Features

  • Query Editor: Write and edit GraphQL operations.
  • Variable Support: Define variables for dynamic queries.
  • Schema Explorer: Browse available types and fields.
  • Auto-Completion: Smart suggestions while typing.
  • Response Viewer: See real-time responses from the API.
  • History: Access previous queries and mutations.

Using the Playground

  1. Write a Query or Mutation

    • Enter your operation in the left pane.

    • Example:

    • query {
        nodes {
          id
          title
        }
      }
  2. Define Variables (If Needed)

    • Click on the "Query Variables" pane at the bottom left.
    • Input variables in JSON format.
  3. Execute the Operation

    • Press the "Play" button (▶️) or use Ctrl + Enter (Cmd + Enter on Mac).
  4. View the Response

    • The response will appear in the right pane.
    • Review data or error messages.
  5. Explore the Schema

    • Use the "Docs" tab on the right to explore the schema.
    • Click on types and fields to see descriptions and details.
  6. Test Subscriptions

    • Write a subscription in the editor.
    • Open multiple tabs to simulate real-time updates.

Tips

  • Auto-Completion

    • Use Ctrl + Space to trigger suggestions.
  • Keyboard Shortcuts

    • Execute: Ctrl + Enter
    • Auto-Complete: Ctrl + Space
  • Save Queries

    • Copy and save frequently used queries for future reference.

Page 3.3.3: Code Examples

Introduction

Below are code examples demonstrating how to interact with the API using various programming languages and tools.

JavaScript Example Using fetch

Fetching a Node

const fetch = require('node-fetch');

const query = `
  query getNode($id: ID!) {
    node(id: $id) {
      id
      title
      data
      children {
        id
        title
      }
    }
  }
`;

const variables = {
  id: '123e4567-e89b-12d3-a456-426614174000',
};

fetch('http://127.0.0.1/api', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    // 'Authorization': 'Bearer YOUR_SESSION_TOKEN', // Include if authentication is required
  },
  body: JSON.stringify({
    query: query,
    variables: variables,
  }),
})
  .then(res => res.json())
  .then(data => console.log(JSON.stringify(data, null, 2)))
  .catch(error => console.error('Error:', error));

 

Python Example Using requests

Creating a Node

import requests

url = 'http://127.0.0.1/api'
headers = {
    'Content-Type': 'application/json',
    # 'Authorization': 'Bearer YOUR_SESSION_TOKEN',  # Include if authentication is required
}

query = '''
mutation createNode($input: CreateNodeInput!) {
  createNode(input: $input) {
    id
    title
    parent {
      id
      title
    }
  }
}
'''

variables = {
    'input': {
        'title': 'Monitors',
        'parentId': '223e4567-e89b-12d3-a456-426614174001',
        'data': None,
    }
}

payload = {
    'query': query,
    'variables': variables,
}

response = requests.post(url, json=payload, headers=headers)
print(response.json())

 

Curl Command

Deleting a Node

curl -X POST http://127.0.0.1/api \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -d '{
    "query": "mutation deleteNode($id: ID!, $option: DeleteOption!) { deleteNode(id: $id, option: $option) { success message } }",
    "variables": {
      "id": "423e4567-e89b-12d3-a456-426614174003",
      "option": "DELETE_CHILDREN"
    }
  }'

 

Notes

  • Replace YOUR_SESSION_TOKEN with a valid token if authentication is required.
  • Ensure that the API server is accessible from your environment.
  • Handle errors appropriately in production code.

Page 3.3.4: Authentication Guidelines

Introduction

Authentication is required for operations that modify data or access sensitive information. The API uses session tokens or cookies to authenticate users.

Obtaining a Session Token

  • Login Mutation

     
    mutation login($username: String!, $password: String!) {
      login(username: $username, password: $password) {
        token
        user {
          id
          username
          isAdmin
        }
      }
    }
  • Example Usage

    Request Variables:

    {
      "username": "admin",
      "password": "YourSecurePassword"
    }
  • Response:

    {
      "data": {
        "login": {
          "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
          "user": {
            "id": "1",
            "username": "admin",
            "isAdmin": true
          }
        }
      }
    }


Using the Session Token

  • Include the Authorization header in your API requests: Authorization: Bearer YOUR_SESSION_TOKEN

  • Example:

    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
    }

Session Management

  • Token Expiration: Tokens may expire after a set period; handle token refresh as needed.

  • Logout Mutation: Invalidate the session token when logging out.

    mutation logout {
      logout {
        success
        message
      }
    }

Security Best Practices

  • Protect Tokens: Do not expose tokens in client-side code or logs.
  • HTTPS: Use secure connections to prevent interception.
  • Least Privilege: Only grant necessary permissions to users.

Administrative Actions

  • Admin Authentication: Administrative mutations require the user to be authenticated as an administrator.
  • Error Handling: If a non-admin user attempts an admin action, the API will return an authorization error.

Error Responses

  • Authentication Errors: Typically return HTTP status code 401 Unauthorized.
  • Authorization Errors: Return 403 Forbidden if the user lacks permissions.

Example Error Response:

{
  "errors": [
    {
      "message": "Not authorized",
      "locations": [{ "line": 2, "column": 3 }],
      "path": ["createUser"]
    }
  ],
  "data": null
}