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 benull
. - 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
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.
- input (
-
Delete User
- id (
ID!
): Unique identifier of the user to delete.
- id (
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
-
Write a Query or Mutation
-
Enter your operation in the left pane.
-
Example:
-
query { nodes { id title } }
-
-
Define Variables (If Needed)
- Click on the "Query Variables" pane at the bottom left.
- Input variables in JSON format.
-
Execute the Operation
- Press the "Play" button (▶️) or use
Ctrl + Enter
(Cmd + Enter
on Mac).
- Press the "Play" button (▶️) or use
-
View the Response
- The response will appear in the right pane.
- Review data or error messages.
-
Explore the Schema
- Use the "Docs" tab on the right to explore the schema.
- Click on types and fields to see descriptions and details.
-
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.
- Use
-
Keyboard Shortcuts
- Execute:
Ctrl + Enter
- Auto-Complete:
Ctrl + Space
- Execute:
-
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
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
}