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 ​