Getting Started with the Pod API: A Step-by-Step Tutorial

Getting Started with the Pod API: A Step-by-Step Tutorial

Download Pod API Postman collection

Welcome to this comprehensive guide on setting up the Pod API locally and making your first API calls to read and write data. This tutorial will walk you through the process of:

  • Setting up the Pod locally.
  • Opening a new Pod instance.
  • Retrieving the existing schema.
  • Creating new schema elements.
  • Adding data to the Pod.

We will provide detailed explanations and examples to help you understand each step. This guide is self-contained and designed to equip you with the knowledge to interact with the Pod API directly.


1. Introduction

The Pod is a personal data storage solution that allows users to securely store and manage their data. It provides an HTTP API that you can use to interact with the data programmatically. This tutorial will guide you through setting up a local instance of the Pod and making your first API calls to read and write data.


2. Prerequisites

Before you begin, ensure you have the following:

  • Docker: The Pod runs in a Docker container.
  • Git: To clone the Pod repository.
  • cURL or similar HTTP client**: To make HTTP requests to the Pod API.
  • Basic knowledge of RESTful APIs and JSON: Familiarity with HTTP methods and JSON formatting will be helpful.

3. Step 1: Set Up the Pod Locally

Use methods determined in official README

3.1 Verify the Pod is Running

Open a new terminal window and use cURL to check the Pod version:

curl http://localhost:3030/version

You should receive a JSON response similar to:

{"cargo":"0.5.4","git_describe":"v0.5.0-31-g4ec3237","build_profile":"release"}

This indicates that the Pod is running and ready to accept requests.


4. Step 2: Open a New Pod

To interact with the Pod, you need to open a new database instance associated with an ownerKey and databaseKey.

4.1 Generate ownerKey and databaseKey

For testing purposes, you can use any 64-character hexadecimal strings. In production, these should be securely generated.

Example:

  • ownerKey: A 64-character hex string (e.g., 64 zeros)
  • databaseKey: Another 64-character hex string (e.g., 64 ones)

You can generate random hex strings using the following command in a Unix terminal:

head -c32 /dev/urandom | xxd -p -c 64

For this tutorial, we’ll use the following keys:

ownerKey="0000000000000000000000000000000000000000000000000000000000000000"
databaseKey="1111111111111111111111111111111111111111111111111111111111111111"

4.2 Open the Pod

Make a POST request to /v4/account/pod/open with the ownerKey and databaseKey:

Request:

curl -X POST http://localhost:3030/v4/account/pod/open \
     -H "Content-Type: application/json" \
     -d '{
           "ownerKey": "0000000000000000000000000000000000000000000000000000000000000000",
           "databaseKey": "1111111111111111111111111111111111111111111111111111111111111111"
         }'

4.3 Verify the Database Creation

At this point, the Pod has created a new database associated with the provided keys. You can proceed to interact with this database.


5. Step 3: Get the Existing Schema

The schema defines the data types and relationships that can be stored in the Pod. Before adding data, it’s helpful to retrieve and understand the existing schema.

5.1 Prepare the Authentication JSON

Most API requests require an auth object for authentication. For clients, the auth object looks like:

{
  "type": "ClientAuth",
  "databaseKey": "1111111111111111111111111111111111111111111111111111111111111111"
}

5.2 Retrieve the Schema

Use the /v5/{ownerKey}/get_schema endpoint to retrieve the existing schema.

Request:

curl -X POST http://localhost:3030/v5/0000000000000000000000000000000000000000000000000000000000000000/get_schema \
     -H "Content-Type: application/json" \
     -d '{
           "auth": {
             "type": "ClientAuth",
             "databaseKey": "1111111111111111111111111111111111111111111111111111111111111111"
           },
           "payload": null
         }'

Response:

You’ll receive a JSON object containing the existing schema elements, such as Account, NavigationItem, etc.

Example response:

{
    "nodes_types": {
        "Trigger": {
            "properties": {
                "dateServerModified": "Integer",
                "action": "Text",
                "id": "Text",
                "filterCreatedAfter": "DateTime",
                "pluginRunId": "Text",
                "triggerOn": "Text",
                "dateCreated": "Integer",
                "filterCreatedAfterPropertyName": "Text",
                "dateModified": "Integer"
            },
            "notNull": [
                "id",
                "dateServerModified",
                "filterCreatedAfter",
                "action",
                "dateCreated",
                "filterCreatedAfterPropertyName",
                "triggerOn",
                "dateModified",
                "pluginRunId"
            ],
            "unique": [
                [
                    "id"
                ]
            ],
            "index": [
                [
                    "dateServerModified",
                    "dateModified",
                    "dateCreated"
                ]
            ]
        }
    },
    "edges_types": {
        "mergedFrom": [
            {
                "source": "Person",
                "target": "Person",
                "properties": {
                    "properties": {},
                    "notNull": [],
                    "unique": [],
                    "index": []
                }
            }
        ]
    },
    "info": {
        "pod": {
            "version": "0.4",
            "url": "https://gitlab.memri.io/memri/pod"
        },
        "cs": {
            "version": "0.2",
            "url": "https://gitlab.memri.io/memri/schema"
        }
    }
}

5.3 Understand the Core Schema Elements

By examining the retrieved schema, you can understand the core data types like Account, NavigationItem, etc., and their properties.


6. Step 4: Create New Schema Elements

To store custom data types in the Pod, you need to define them in the schema by sending a request to the /v5/{ownerKey}/schema endpoint.

6.1 Define Your Schema Payload

Suppose you want to create a new item type called TestType with properties testProperty (Text) and secondTestProperty (Integer), and define an edge called testEdge from TestType to Account.

Here’s the payload to add new schema elements:

{
  "auth": {
    "type": "ClientAuth",
    "databaseKey": "1111111111111111111111111111111111111111111111111111111111111111"
  },
  "payload": {
    "meta": {
      "name": "memriOne",
      "url": "https://gitlab.memri.io/memri/consumer_app",
      "version": "0.1"
    },
    "nodes": {
      "TestType": {
        "properties": {
          "testProperty": "Text",
          "secondTestProperty": "Integer"
        }
      }
    },
    "edges": {
      "testEdge": [
        {
          "source": "TestType",
          "target": "Account"
        }
      ]
    }
  }
}

6.2 Send the Schema Creation Request

Use the /v5/{ownerKey}/schema endpoint to create new schema elements.

Request:

curl -X POST http://localhost:3030/v5/0000000000000000000000000000000000000000000000000000000000000000/schema \
     -H "Content-Type: application/json" \
     -d '{
           "auth": {
             "type": "ClientAuth",
             "databaseKey": "1111111111111111111111111111111111111111111111111111111111111111"
           },
           "payload": {
             "meta": {
               "name": "memriOne",
               "url": "https://gitlab.memri.io/memri/consumer_app",
               "version": "0.1"
             },
             "nodes": {
               "TestType": {
                 "properties": {
                   "testProperty": "Text",
                   "secondTestProperty": "Integer"
                 }
               }
             },
             "edges": {
               "testEdge": [
                 {
                   "source": "TestType",
                   "target": "Account"
                 }
               ]
             }
           }
         }'

6.3 Verify the New Schema Elements

Retrieve the schema again using the /v5/{ownerKey}/get_schema endpoint to confirm that the new schema elements have been added.

Request:

curl -X POST http://localhost:3030/v5/0000000000000000000000000000000000000000000000000000000000000000/get_schema \
     -H "Content-Type: application/json" \
     -d '{
           "auth": {
             "type": "ClientAuth",
             "databaseKey": "1111111111111111111111111111111111111111111111111111111111111111"
           }
         }'

Response:

You’ll see your newly added TestType and testEdge in the schema.


7. Step 5: Add Data to the Pod

With the schema in place, you can now add data to your Pod. You can perform multiple operations in a single request using the /v4/{ownerKey}/bulk endpoint or use separate endpoints for individual operations.

7.1 Using the Bulk Endpoint

7.1.1 Prepare the Bulk Operations Payload

Here’s an example payload to create an item of type TestType:

{
  "auth": {
    "type": "ClientAuth",
    "databaseKey": "1111111111111111111111111111111111111111111111111111111111111111"
  },
  "payload": {
    "createItems": [
      {
        "type": "TestType",
        "testProperty": "Hello, World!",
        "secondTestProperty": 42
      }
    ],
    "updateItems": [],
    "deleteItems": [],
    "createEdges": []
  }
}

7.1.2 Send the Bulk Operations Request

Request:

curl -X POST http://localhost:3030/v4/0000000000000000000000000000000000000000000000000000000000000000/bulk \
     -H "Content-Type: application/json" \
     -d '{
           "auth": {
             "type": "ClientAuth",
             "databaseKey": "1111111111111111111111111111111111111111111111111111111111111111"
           },
           "payload": {
             "createItems": [
               {
                 "type": "TestType",
                 "testProperty": "Hello, World!",
                 "secondTestProperty": 42
               }
             ],
             "updateItems": [],
             "deleteItems": [],
             "createEdges": []
           }
         }'

Response:

JSON object with {"createItems":["generated-item-id"],"createEdges":[],"search":[]} indicates success.

7.1.3 Retrieve the Created Item

To verify that the item was created, you can use the /v4/{ownerKey}/search endpoint.

Request:

curl -X POST http://localhost:3030/v4/0000000000000000000000000000000000000000000000000000000000000000/search \
     -H "Content-Type: application/json" \
     -d '{
           "auth": {
             "type": "ClientAuth",
             "databaseKey": "1111111111111111111111111111111111111111111111111111111111111111"
           },
           "payload": {
             "type": "TestType",
             "_limit": 10
           }
         }'

Response:

You’ll receive an array of items of type TestType, including the one you just created.

Example response:

[
  {
    "id": "abcd1234efgh5678ijkl9012mnop3456",
    "type": "TestType",
    "testProperty": "Hello, World!",
    "secondTestProperty": 42,
    "dateCreated": "2021-10-01T12:00:00Z",
    "dateModified": "2021-10-01T12:00:00Z",
    "deleted": false
  }
]

7.2 Using Separate Endpoints

Alternatively, you can use individual endpoints to perform operations.

7.2.1 Create an Item

Request:

curl -X POST http://localhost:3030/v4/0000000000000000000000000000000000000000000000000000000000000000/create_item \
     -H "Content-Type: application/json" \
     -d '{
           "auth": {
             "type": "ClientAuth",
             "databaseKey": "1111111111111111111111111111111111111111111111111111111111111111"
           },
           "payload": {
             "type": "TestType",
             "testProperty": "Another Item",
             "secondTestProperty": 24
           }
         }'

Response:

id of the created item.

7.2.2 Update an Item

Suppose you want to update the testProperty of an item with id 93f9c7d62cf44175b6e2a65afd62b1e4.

Request:

curl -X POST http://localhost:3030/v4/0000000000000000000000000000000000000000000000000000000000000000/update_item \
     -H "Content-Type: application/json" \
     -d '{
           "auth": {
             "type": "ClientAuth",
             "databaseKey": "1111111111111111111111111111111111111111111111111111111111111111"
           },
           "payload": {
             "id": "93f9c7d62cf44175b6e2a65afd62b1e4",
             "testProperty": "Updated Value"
           }
         }'

7.2.3 Delete an Item

To delete an item with id 93f9c7d62cf44175b6e2a65afd62b1e4.

Request:

curl -X POST http://localhost:3030/v4/0000000000000000000000000000000000000000000000000000000000000000/delete_item \
     -H "Content-Type: application/json" \
     -d '{
           "auth": {
             "type": "ClientAuth",
             "databaseKey": "1111111111111111111111111111111111111111111111111111111111111111"
           },
           "payload": "abcd1234efgh5678ijkl9012mnop3456"
         }'

7.3 Create Edges

Assuming you have an Account item with id account1234567890abcdef, you can create an edge from the TestType item to the Account item.

7.3.1 Create the Edge

Request:

curl -X POST http://localhost:3030/v4/0000000000000000000000000000000000000000000000000000000000000000/create_edge \
     -H "Content-Type: application/json" \
     -d '{
           "auth": {
             "type": "ClientAuth",
             "databaseKey": "1111111111111111111111111111111111111111111111111111111111111111"
           },
           "payload": {
             "_source": "abcd1234efgh5678ijkl9012mnop3456",
             "_target": "account1234567890abcdef",
             "_name": "testEdge"
           }
         }'

Response:

An object with the id of the created edge.

7.3.2 Retrieve Edges

To verify the edge, you can retrieve edges of the TestType item.

Request:

curl -X POST http://localhost:3030/v4/0000000000000000000000000000000000000000000000000000000000000000/get_edges \
     -H "Content-Type: application/json" \
     -d '{
           "auth": {
             "type": "ClientAuth",
             "databaseKey": "1111111111111111111111111111111111111111111111111111111111111111"
           },
           "payload": {
             "item": "abcd1234efgh5678ijkl9012mnop3456",
             "direction": "Outgoing",
             "expandItems": true
           }
         }'

Response:

An array of edges:

[
  {
    "name": "testEdge",
    "item": {
      "id": "account1234567890abcdef",
      "type": "Account",
      "displayName": "John Doe",
      "service": "ExampleService",
      // ... other properties
    }
  }
]

7.4 Use GraphQL Endpoint

You can use the GraphQL endpoint to perform complex queries.

7.4.1 Prepare the GraphQL Query

Example query to retrieve TestType items and their associated Account:

{
  TestType {
    id
    testProperty
    secondTestProperty
    testEdge {
      id
      displayName
    }
  }
}

7.4.2 Send the GraphQL Request

Request:

curl -X POST http://localhost:3030/v4/0000000000000000000000000000000000000000000000000000000000000000/graphql \
     -H "Content-Type: application/json" \
     -d '{
           "auth": {
             "type": "ClientAuth",
             "databaseKey": "1111111111111111111111111111111111111111111111111111111111111111"
           },
           "payload": "query { TestType { id testProperty secondTestProperty testEdge { id displayName } } }"
           }
         }'

Response:

You’ll receive data matching your query.

Example response:

{
  "data": {
    "TestType": [
      {
        "id": "abcd1234efgh5678ijkl9012mnop3456",
        "testProperty": "Hello, World!",
        "secondTestProperty": 42,
        "testEdge": [
          {
            "id": "account1234567890abcdef",
            "displayName": "John Doe"
          }
        ]
      }
    ]
  }
}

8. Conclusion

You have successfully set up the Pod locally, retrieved the existing schema, created custom schema elements, added data, and made your first API calls to read and write data. By following these steps, you can now extend the Pod with your own data types and build applications that interact with the Pod API.


9. Additional Material

For more information on the Pod API, including all available endpoints and their usage, refer to the official API documentation or contact the maintainers for access to the latest resources.

Important Endpoints

Here is a summary of some of the important endpoints used in this tutorial:

Open Pod

  • Endpoint: POST /v4/account/pod/open

  • Description: Creates the database in the Pod with the given ownerKey and databaseKey.

  • Payload:

    {
      "ownerKey": "securely generated hex string of length 64 characters",
      "databaseKey": "securely generated hex string of length 64 characters"
    }
    

Get Schema

  • Endpoint: POST /v5/{ownerKey}/get_schema

  • Description: Retrieves the existing schema from the Pod.

  • Payload:

    {
      "auth": { "type": "ClientAuth", "databaseKey": "..." }
    }
    

Update Schema

  • Endpoint: POST /v5/{ownerKey}/schema

  • Description: Updates the schema with new elements.

  • Payload:

    {
      "auth": { "type": "ClientAuth", "databaseKey": "..." },
      "payload": { "meta": {...}, "nodes": {...}, "edges": {...} }
    }
    

Create Item

  • Endpoint: POST /v4/{ownerKey}/create_item

  • Description: Creates a single item in the Pod.

  • Payload:

    {
      "auth": { "type": "ClientAuth", "databaseKey": "..." },
      "payload": { "type": "YourType", ... }
    }
    

Update Item

  • Endpoint: POST /v4/{ownerKey}/update_item

  • Description: Updates an existing item.

  • Payload:

    {
      "auth": { "type": "ClientAuth", "databaseKey": "..." },
      "payload": { "id": "item_id", ... }
    }
    

Delete Item

  • Endpoint: POST /v4/{ownerKey}/delete_item

  • Description: Deletes an item by marking it as deleted.

  • Payload:

    {
      "auth": { "type": "ClientAuth", "databaseKey": "..." },
      "payload": "item_id"
    }
    

Create Edge

  • Endpoint: POST /v4/{ownerKey}/create_edge

  • Description: Creates a directed edge between two existing items.

  • Payload:

    {
      "auth": { "type": "ClientAuth", "databaseKey": "..." },
      "payload": {
        "_source": "source_item_id",
        "_target": "target_item_id",
        "_name": "edge_name"
      }
    }
    

Get Edges

  • Endpoint: POST /v4/{ownerKey}/get_edges

  • Description: Retrieves edges of a specified item.

  • Payload:

    {
      "auth": { "type": "ClientAuth", "databaseKey": "..." },
      "payload": {
        "item": "item_id",
        "direction": "Outgoing",
        "expandItems": true
      }
    }
    

Search Items

  • Endpoint: POST /v4/{ownerKey}/search

  • Description: Searches for items based on provided criteria.

  • Payload:

    {
      "auth": { "type": "ClientAuth", "databaseKey": "..." },
      "payload": {
        "type": "ItemType",
        "_limit": 10
      }
    }
    

Bulk Operations

  • Endpoint: POST /v4/{ownerKey}/bulk

  • Description: Performs multiple operations in a single request.

  • Payload:

    {
      "auth": { "type": "ClientAuth", "databaseKey": "..." },
      "payload": {
        "createItems": [...],
        "updateItems": [...],
        "deleteItems": [...],
        "createEdges": [...],
        "search": [...]
      }
    }
    

GraphQL Query

  • Endpoint: POST /v4/{ownerKey}/graphql

  • Description: Executes a GraphQL query.

  • Payload:

    {
      "auth": { "type": "ClientAuth", "databaseKey": "..." },
      "payload": "query"
    }
    

Thank you for following this tutorial. If you have any questions or need further assistance, feel free to reach out.