Skip to content

GoLang SDK

github | pkg.go.dev

Installation

shell
go get github.com/jsonbankio/go-sdk

Initialize

JsonBank can be initialized with or without api keys.
Api Keys are only required when you want to access private/secured documents

go
package main

import "github.com/jsonbankio/go-sdk"

func main() {
	// Initialize the client
	jsb := jsonbank.InitWithoutKeys()
}
go
package main

import "github.com/jsonbankio/go-sdk"

func main() {
	// Initialize the client
	jsb := jsonbank.Init(jsonbank.Config{
		Keys: jsonbank.Keys{
			Public:  "your public key",
			Private: "your private key",
		},
	})
}

Access Keys

  • Public key: read-only. Use it to Authenticate() and to read your own private documents. Public documents need no key at all.
  • Private key: write-only, only needed to create, update or delete documents.

Check Authentication

To check if the user is authenticated, use the Authenticated method.
Make sure to have called Authenticate method before.

go
authenticated, err := jsb.Authenticate()

if err != nil {
   panic(err)
}

fmt.Println("Authenticated:", jsb.Authenticated())
fmt.Println("Authenticated as:", authenticated.Username)

Public Content Methods

Public contents do not require authentication.

GetDocumentMeta()

Get a public document meta details either by id or path. This method does not return the content of the document. To get the content, use GetContent method.

go
meta, err := jsb.GetDocumentMeta("jsonbank/sdk-test/index.json")
if err != nil {
	panic(err)
}

fmt.Println(meta.Id)          // id of the document
fmt.Println(meta.Project)     // project of the document
fmt.Println(meta.Name)        // name of the document
fmt.Println(meta.Path)        // path of the document
fmt.Println(meta.ContentSize) // size of the document
fmt.Println(meta.UpdatedAt)   // last update time
fmt.Println(meta.CreatedAt)   // creation time
go
// meta is of type *types.DocumentMeta
type DocumentMeta struct {
	Id          string      `json:"id"`
	Name        string      `json:"name"`
	Project     string      `json:"project"`
	Path        string      `json:"path"`
	ContentSize ContentSize `json:"contentSize"`
	FolderId    string      `json:"folderId"`
	UpdatedAt   string      `json:"updatedAt"`
	CreatedAt   string      `json:"createdAt"`
}

type ContentSize struct {
	Number float64 `json:"number"`
	String string  `json:"string"`
}

GetContent()

Get a public document content either by id or path. It returns the parsed json as any, so cast it to the type you expect.

go
data, err := jsb.GetContent("jsonbank/sdk-test/index.json")
if err != nil {
	panic(err)
}

// data is of type any, cast it to use it
content := data.(map[string]interface{})
fmt.Println(content["author"]) // jsonbank
json
{
  "name": "JsonBank SDK Test File",
  "author": "jsonbank"
}

GetContentAsString()

Get a public document content either by id or path as a string. It returns the raw json string.

go
data, err := jsb.GetContentAsString("jsonbank/sdk-test/index.json")
// data is a string

GetGithubContent()

Get the contents of a public json file from github. This will read from the default branch of the repo.

Note: Referenced file must be a public json file.
go
data, err := jsb.GetGithubContent("org/repo/file.json")

// example
result, err := jsb.GetGithubContent("jsonbankio/documentation/github-test.json")

// result is of any type, cast it to use it

GetGithubContentAsString()

Same as GetGithubContent but returns the content as a string.

Note: Referenced file must be a public json file.
go
data, err := jsb.GetGithubContentAsString("org/repo/file.json")

// example
result, err := jsb.GetGithubContentAsString("jsonbankio/documentation/github-test.json")

Access Own Content

Your own content is the documents in your projects. To read them, initialize with your api keys and authenticate first. See With Api Keys for more details.

Note: These methods need your public api key. Call Authenticate() before using them.

GetOwnContent()

Get one of your documents either by id or path. Works for private documents too. It returns the parsed json as any.

go
data, err := jsb.GetOwnContent("sdk-test/index.json")
if err != nil {
	panic(err)
}

content := data.(map[string]interface{})

GetOwnContentAsString()

Same as GetOwnContent but returns the raw json string.

go
data, err := jsb.GetOwnContentAsString("sdk-test/index.json")
// data is a string

GetOwnDocumentMeta()

Get the meta of one of your documents either by id or path. Returns the same *types.DocumentMeta as GetDocumentMeta.

go
meta, err := jsb.GetOwnDocumentMeta("sdk-test/index.json")

HasOwnDocument()

Check if one of your documents exists, either by id or path.

go
exists := jsb.HasOwnDocument("sdk-test/index.json") // true
Note: Returns false instead of an error when the document is not found.

Managing Content

Create, update and delete documents in your projects. The body structs live in the types package: import "github.com/jsonbankio/go-sdk/types".

Note: These methods need your private api key.

CreateDocument()

Create a new document in a project. Folder is optional, leave it out to create at the project root. Content is a json string.

go
doc, err := jsb.CreateDocument(types.CreateDocumentBody{
	Name:    "index.json",
	Project: "sdk-test",
	Folder:  "folder", // optional
	Content: `{ "name": "JsonBank SDK Test File", "author": "jsonbank" }`,
})
go
// doc is of type *types.NewDocument
type NewDocument struct {
	Id        string `json:"id"`
	Name      string `json:"name"`
	Path      string `json:"path"`
	Project   string `json:"project"`
	CreatedAt string `json:"createdAt"`
	Exists    bool   `json:"exists"`
}

CreateDocumentIfNotExists()

Same as CreateDocument, but if the document already exists it is fetched and returned instead of erroring.

go
doc, err := jsb.CreateDocumentIfNotExists(types.CreateDocumentBody{
	Name:    "index.json",
	Project: "sdk-test",
	Content: `{ "name": "JsonBank SDK Test File", "author": "jsonbank" }`,
})

// when it already existed
fmt.Println(doc.Exists) // true

UpdateOwnDocument()

Update the content of one of your documents either by id or path. content is a json string.

go
res, err := jsb.UpdateOwnDocument("sdk-test/index.json", `{
	"name": "JsonBank SDK Test File",
	"author": "jsonbank",
	"updated": true
}`)

fmt.Println(res.Changed) // true
go
// res is of type *types.UpdatedDocument
type UpdatedDocument struct {
	Changed bool `json:"changed"`
}

DeleteDocument()

Delete one of your documents either by id or path.

go
res, err := jsb.DeleteDocument("sdk-test/folder/new_doc.json")
// res.Deleted is true when the document was removed

Folders

Group documents into folders inside a project.

GetFolder()

Get a folder either by id or path.

go
folder, err := jsb.GetFolder("sdk-test/folder")
go
// folder is of type *types.Folder
type Folder struct {
	Id           string       `json:"id"`
	Name         string       `json:"name"`
	Path         string       `json:"path"`
	Project      string       `json:"project"`
	ParentFolder string       `json:"parentFolder"`
	CreatedAt    string       `json:"createdAt"`
	UpdatedAt    string       `json:"updatedAt"`
	Stats        *FolderStats `json:"stats,omitempty"`
}

type FolderStats struct {
	Documents float64 `json:"documents"`
	Folders   float64 `json:"folders"`
}

GetFolderWithStats()

Same as GetFolder but also fills in Stats (how many documents and folders are inside).

go
folder, err := jsb.GetFolderWithStats("sdk-test/folder")

fmt.Println(folder.Stats.Documents)
fmt.Println(folder.Stats.Folders)

CreateFolder()

Create a new folder in a project. Folder is optional, use it to nest inside another folder.

go
folder, err := jsb.CreateFolder(types.CreateFolderBody{
	Name:    "folder",
	Project: "sdk-test",
})

CreateFolderIfNotExists()

Same as CreateFolder, but if the folder already exists it is fetched and returned instead of erroring.

go
folder, err := jsb.CreateFolderIfNotExists(types.CreateFolderBody{
	Name:    "folder",
	Project: "sdk-test",
})

// when it already existed
fmt.Println(folder.Exists) // true

Listing

Browse what is inside a project, one level deep. Use these when you do not already know the ids or paths of your documents and folders. The params structs live in the types package: import "github.com/jsonbankio/go-sdk/types".

Note: These methods need your public api key. Call Authenticate() before using them.

ScanProject()

List the documents and folders of a project together. Pass an empty types.ScanProjectParams{} to list the project root, or set Folder to list inside a folder.

go
listing, err := jsb.ScanProject("sdk-test", types.ScanProjectParams{})
if err != nil {
	panic(err)
}

fmt.Println(listing.Project.Slug)         // sdk-test
fmt.Println(len(listing.Documents.Data))  // documents on this page
fmt.Println(listing.Documents.Meta.Total) // documents in total
fmt.Println(len(listing.Folders.Data))    // folders on this page
go
// listing is of type *types.ScanProjectResponse
type ScanProjectResponse struct {
	Project ListedProject `json:"project"`
	// nil when the project root was listed
	Folder    *ListedFolder      `json:"folder,omitempty"`
	Documents PaginatedDocuments `json:"documents"`
	Folders   PaginatedFolders   `json:"folders"`
}

type ListedProject struct {
	Slug   string `json:"slug"`
	Title  string `json:"title"`
	Access string `json:"access"`
}

type ListedFolder struct {
	Id           string `json:"id"`
	Name         string `json:"name"`
	Path         string `json:"path"`
	ParentFolder string `json:"parentFolder,omitempty"`
}

type PaginatedDocuments struct {
	Data []DocumentMeta `json:"data"`
	Meta PaginationMeta `json:"meta"`
}

type PaginatedFolders struct {
	Data []Folder       `json:"data"`
	Meta PaginationMeta `json:"meta"`
}

type PaginationMeta struct {
	Page     int `json:"page"`
	PerPage  int `json:"perPage"`
	Total    int `json:"total"`
	LastPage int `json:"lastPage"`
}

Each entry in Documents.Data is a DocumentMeta and each entry in Folders.Data is a Folder.

To scan inside a folder, set Folder to its id or its path. The folder you asked for comes back as listing.Folder.

go
listing, err := jsb.ScanProject("sdk-test", types.ScanProjectParams{
	Folder: "folder",
})

fmt.Println(listing.Folder.Path) // folder
Note:Folder is a pointer and is only set when you asked for one. It is nil when the project root was listed, so check it before dereferencing.

ListDocuments()

Same as ScanProject without the folders, so nothing you do not need is queried or paged. Content is not included, fetch it with GetOwnContent.

go
listing, err := jsb.ListDocuments("sdk-test", types.ListParams{
	PerPage: 50,
})
if err != nil {
	panic(err)
}

for _, doc := range listing.Documents.Data {
	fmt.Println(doc.Path, doc.ContentSize.String)
}
go
// listing is of type *types.ListDocumentsResponse
type ListDocumentsResponse struct {
	Project   ListedProject      `json:"project"`
	Folder    *ListedFolder      `json:"folder,omitempty"`
	Documents PaginatedDocuments `json:"documents"`
}

ListFolders()

Same as ScanProject without the documents.

go
listing, err := jsb.ListFolders("sdk-test", types.ListParams{
	Sort:  types.SortByCreatedAt,
	Order: types.OrderDesc,
})
if err != nil {
	panic(err)
}

for _, folder := range listing.Folders.Data {
	fmt.Println(folder.Path)
}
go
// listing is of type *types.ListFoldersResponse
type ListFoldersResponse struct {
	Project ListedProject    `json:"project"`
	Folder  *ListedFolder    `json:"folder,omitempty"`
	Folders PaginatedFolders `json:"folders"`
}

Listing params

Every field is optional. Leave one at its zero value and the server default is used.

ListDocuments and ListFolders return a single list, so types.ListParams carries a single page and size:

  • Folder: folder id or path to list inside. Leave it empty to list the project root.
  • Page: page to return. Defaults to 1.
  • PerPage: results per page, up to 1000. Defaults to 100.
  • Sort: field to sort by, one of types.SortByName (default), types.SortByCreatedAt or types.SortByUpdatedAt.
  • Order: types.OrderAsc (default) or types.OrderDesc.

ScanProject returns two lists that paginate independently, so types.ScanProjectParams carries a page and a size for each:

  • Folder, Sort, Order: same as above, Sort and Order apply to both lists.
  • DocumentsPage, DocumentsPerPage: pagination of the documents list.
  • FoldersPage, FoldersPerPage: pagination of the folders list.

Paginating

Each list is a single page. Read Meta.LastPage to know how many there are and walk them:

go
page, lastPage := 1, 1

for page <= lastPage {
	listing, err := jsb.ListDocuments("sdk-test", types.ListParams{
		Page:    page,
		PerPage: 1000,
	})
	if err != nil {
		panic(err)
	}

	lastPage = listing.Documents.Meta.LastPage

	for _, doc := range listing.Documents.Data {
		fmt.Println(doc.Path)
	}

	page++
}

Uploading Files

Upload a json file straight from your file system.

UploadDocument()

Reads a file from disk and creates a document from it. Name and Folder are optional, Name defaults to the file name.

go
doc, err := jsb.UploadDocument(types.UploadDocumentBody{
	FilePath: "./tests/upload.json",
	Project:  "sdk-test",
	Folder:   "folder", // optional
})
go
// doc is of type *types.NewDocument
type NewDocument struct {
	Id        string `json:"id"`
	Name      string `json:"name"`
	Path      string `json:"path"`
	Project   string `json:"project"`
	CreatedAt string `json:"createdAt"`
	Exists    bool   `json:"exists"`
}

Error Handling

Methods return a *jsonbank.RequestError when something goes wrong. It has a Code you can check.

go
folder, err := jsb.CreateFolder(types.CreateFolderBody{
	Name:    "folder",
	Project: "sdk-test",
})
if err != nil {
	// err is *jsonbank.RequestError
	if err.Code == "name.exists" {
		// folder already exists, ignore it or fetch it instead
	} else {
		panic(err)
	}
}

Common error codes:

  • notFound: the document or folder does not exist.
  • name.exists: a document or folder with that name already exists.
Note:HasOwnDocument() returns false instead of an error, and the ...IfNotExists() methods return the existing item with Exists: true.

Next steps