A Go SDK for interacting with the Anytype API to manage spaces, objects, and perform searches. This library provides a feature-rich, fluent interface to integrate Anytype functionality into your Go applications.
- π Overview
- π₯ Installation
- π¦ Quick Start
- π§ Advanced Examples
- π‘ Design Philosophy
- π API Reference
- β Best Practices
- π§ Troubleshooting
- π§ͺ Testing
- π₯ Contributing
- π License
Anytype-Go provides a Go SDK for interacting with Anytype's local API. This SDK offers a clean, fluent interface for:
- Managing spaces and their members
- Creating, reading, updating, and deleting objects
- Searching for objects using various filters
- Exporting objects to different formats
- Working with object types, templates, and properties
go get github.com/epheo/anytype-go
Import both the main package and client implementation:
import (
"github.com/epheo/anytype-go"
_ "github.com/epheo/anytype-go/client" // Register client implementation
)
π More complete examples can be found in the examples directory, including full implementations of authentication, working with spaces, objects, and more.
To use the Anytype API, you need to obtain an AppKey and SessionToken. Here's how to get them:
// Step 1: Initiate authentication and get challenge ID
authResponse, err := client.Auth().DisplayCode(ctx, "MyAnytypeApp")
if err != nil {
log.Fatalf("Failed to initiate authentication: %v", err)
}
challengeID := authResponse.ChallengeID
// Step 2: User needs to enter the code shown in Anytype app
fmt.Println("Please enter the authentication code shown in Anytype:")
var code string
fmt.Scanln(&code)
// Step 3: Complete authentication and get tokens
tokenResponse, err := client.Auth().GetToken(ctx, challengeID, code)
if err != nil {
log.Fatalf("Authentication failed: %v", err)
}
// Now you have your authentication tokens
appKey := tokenResponse.AppKey
sessionToken := tokenResponse.SessionToken
// Create authenticated client
client := anytype.NewClient(
anytype.WithBaseURL("http://localhost:31009"), // Default Anytype local API URL
anytype.WithAppKey(appKey),
anytype.WithSessionToken(sessionToken),
)
Note: The authentication flow requires user interaction. When you call
DisplayCode
, Anytype will show a verification code that must be entered in your application.
// List all spaces
spaces, err := client.Spaces().List(ctx)
// Get a specific space
space, err := client.Space(spaceID).Get(ctx)
// Create a new space
newSpace, err := client.Spaces().Create(ctx, anytype.CreateSpaceRequest{
Name: "My New Workspace",
Description: "Created via the Go SDK",
})
// Get an object
object, err := client.Space(spaceID).Object(objectID).Get(ctx)
// Delete an object
err = client.Space(spaceID).Object(objectID).Delete(ctx)
// Export an object to markdown
exportResult, err := client.Space(spaceID).Object(objectID).Export(ctx, "markdown")
// Create a new object
newObject, err := client.Space(spaceID).Objects().Create(ctx, anytype.CreateObjectRequest{
TypeKey: "ot-page",
Name: "My New Page",
Description: "Created via the Go SDK",
Body: "# This is a new page\n\nWith some content in markdown format.",
Icon: &anytype.Icon{
Type: "emoji",
Value: "π",
},
})
// Search within a specific space
results, err := client.Space(spaceID).Search(ctx, anytype.SearchRequest{
Query: "important notes",
Sort: anytype.SortOptions{
Property: anytype.SortPropertyLastModifiedDate,
Direction: anytype.SortDirectionDesc,
},
Types: []string{"ot-note", "ot-page"}, // Filter by specific types
})
// List available object types in a space
objectTypes, err := client.Space(spaceID).Types().List(ctx)
// Get details of a specific object type
typeDetails, err := client.Space(spaceID).Type(typeID).Get(ctx)
// Create a new template based on an object type
newTemplate, err := client.Space(spaceID).Templates().Create(ctx, anytype.CreateTemplateRequest{
Name: "Project Template",
Description: "Template for project documentation",
TypeID: typeID,
Icon: &anytype.Icon{
Type: "emoji",
Value: "π",
},
DefaultProperties: []string{"name", "description", "status", "deadline"},
})
// Get a specific template
template, err := client.Space(spaceID).Template(templateID).Get(ctx)
// Update object properties
err := client.Space(spaceID).Object(objectID).UpdateProperties(ctx, anytype.UpdatePropertiesRequest{
Properties: map[string]interface{}{
"name": "Updated Title",
"description": "Updated description",
"status": "In Progress",
"priority": "High",
"deadline": time.Now().AddDate(0, 0, 14).Format(time.RFC3339),
},
})
// Add a relation to another object
err := client.Space(spaceID).Object(objectID).AddRelation(ctx, relatedObjectID, "related-to")
// Create a new list to organize objects
newList, err := client.Space(spaceID).Lists().Create(ctx, anytype.CreateListRequest{
Name: "Project Tasks",
Description: "All tasks for our current project",
Icon: &anytype.Icon{
Type: "emoji",
Value: "π",
},
})
// Add objects to a list
err := client.Space(spaceID).List(listID).AddObjects(ctx, []string{objectID1, objectID2})
// Create a custom view for a list
newView, err := client.Space(spaceID).List(listID).Views().Create(ctx, anytype.CreateViewRequest{
Name: "Priority View",
Type: "board",
GroupBy: []string{"priority"},
SortBy: []anytype.SortOptions{
{
Property: "deadline",
Direction: anytype.SortDirectionAsc,
},
},
Filters: []anytype.FilterCondition{
{
Property: "status",
Operator: anytype.OperatorNotEquals,
Value: "Completed",
},
},
})
The Anytype-Go SDK is built around three core design principles:
exportedMarkdown, err := client.
Space(spaceID).
Object(objectID).
Export(ctx, "markdown")
Benefits:
- Readable code that mirrors natural language
- IDE autocomplete reveals available operations
- Compile-time type safety
- Reduced boilerplate code
The SDK is organized around Anytype's core concepts (spaces, objects, types) with interfaces that map directly to these concepts:
SpaceClient
andSpaceContext
for spacesObjectClient
andObjectContext
for objectsTypeClient
for object typesListClient
for lists and views
The naming of interfaces and types in this library follows a clear and consistent pattern to improve code readability and API fluency:
<Entity>Client
: Represents a client that operates on collections of entities (e.g.,SpaceClient
for working with multiple spaces,TypeClient
for working with multiple object types). These clients handle operations like listing, searching, and creating new entities.<Entity>Context
: Represents a client that operates on a single, specific entity instance (e.g.,SpaceContext
for a single space,ObjectContext
for a single object). These handle operations like getting details, updating, or deleting a specific entity.
This naming convention creates a fluent, chainable API where:
- Collection operations use the
<Entity>Client
pattern (e.g.,client.Spaces().List()
) - Instance operations use the
<Entity>Context
pattern (e.g.,client.Space(spaceID).Get()
) - Nested resources follow a natural hierarchy (e.g.,
client.Space(spaceID).Object(objectID).Export()
)
This design enables intuitive navigation through the API that mirrors natural language and domain concepts.
HTTP Request β ValidationMiddleware β RetryMiddleware β DisconnectMiddleware β HTTP Client β API
Each middleware handles a specific concern:
- Validation: Validates requests before sending
- Retry: Handles transient errors with configurable policies
- Disconnect: Manages network interruptions
For detailed API documentation, see GoDoc.
- Reuse the client instance across your application
- Use context for cancellation to control timeouts
- Handle rate limiting with appropriate backoff strategies
- Validate inputs before making API calls
- Check for errors and handle them appropriately
- Use the fluent interface for cleaner, more readable code
- Authentication Failures**: Verify your app key and session token
- Connection Issues**: Ensure Anytype is running locally
- Rate Limiting**: Implement backoff if making many requests
The SDK testing approach focuses on behavior verification using mock implementations:
tests
: Tests ensure that client interfaces behave according to specifications using mock implementations to simulate API responses.
go test -v ./tests/...
tests_api_coverage
: Tests verify that all API endpoints are properly defined and can be called with appropriate parameters.
go test -v ./tests_api_coverage/...
The test infrastructure uses mock implementations (in tests/mocks
) to simulate the Anytype API, allowing thorough testing without requiring a running Anytype instance.
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Create a new Pull Request
Apache License 2.0 - see LICENSE file for details.