GoLang SDK
Installation
go get github.com/jsonbankio/go-sdkInitialize
JsonBank can be initialized with or without api keys.
Api Keys are only required when you want to access private/secured documents
package main
import "github.com/jsonbankio/go-sdk"
func main() {
// Initialize the client
jsb := jsonbank.InitWithoutKeys()
}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.
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.
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// 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.
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{
"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.
data, err := jsb.GetContentAsString("jsonbank/sdk-test/index.json")
// data is a stringGetGithubContent()
Get the contents of a public json file from github. This will read from the default branch of the repo.
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 itGetGithubContentAsString()
Same as GetGithubContent but returns the content as a string.
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.
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.
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.
data, err := jsb.GetOwnContentAsString("sdk-test/index.json")
// data is a stringGetOwnDocumentMeta()
Get the meta of one of your documents either by id or path. Returns the same *types.DocumentMeta as GetDocumentMeta.
meta, err := jsb.GetOwnDocumentMeta("sdk-test/index.json")HasOwnDocument()
Check if one of your documents exists, either by id or path.
exists := jsb.HasOwnDocument("sdk-test/index.json") // truefalse 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".
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.
doc, err := jsb.CreateDocument(types.CreateDocumentBody{
Name: "index.json",
Project: "sdk-test",
Folder: "folder", // optional
Content: `{ "name": "JsonBank SDK Test File", "author": "jsonbank" }`,
})// 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.
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) // trueUpdateOwnDocument()
Update the content of one of your documents either by id or path. content is a json string.
res, err := jsb.UpdateOwnDocument("sdk-test/index.json", `{
"name": "JsonBank SDK Test File",
"author": "jsonbank",
"updated": true
}`)
fmt.Println(res.Changed) // true// res is of type *types.UpdatedDocument
type UpdatedDocument struct {
Changed bool `json:"changed"`
}DeleteDocument()
Delete one of your documents either by id or path.
res, err := jsb.DeleteDocument("sdk-test/folder/new_doc.json")
// res.Deleted is true when the document was removedFolders
Group documents into folders inside a project.
GetFolder()
Get a folder either by id or path.
folder, err := jsb.GetFolder("sdk-test/folder")// 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).
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.
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.
folder, err := jsb.CreateFolderIfNotExists(types.CreateFolderBody{
Name: "folder",
Project: "sdk-test",
})
// when it already existed
fmt.Println(folder.Exists) // trueListing
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".
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.
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// 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.
listing, err := jsb.ScanProject("sdk-test", types.ScanProjectParams{
Folder: "folder",
})
fmt.Println(listing.Folder.Path) // folderFolder 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.
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)
}// 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.
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)
}// 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
idorpathto 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 to100. - Sort: field to sort by, one of
types.SortByName(default),types.SortByCreatedAtortypes.SortByUpdatedAt. - Order:
types.OrderAsc(default) ortypes.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,
SortandOrderapply 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:
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.
doc, err := jsb.UploadDocument(types.UploadDocumentBody{
FilePath: "./tests/upload.json",
Project: "sdk-test",
Folder: "folder", // optional
})// 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.
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.
HasOwnDocument() returns false instead of an error, and the ...IfNotExists() methods return the existing item with Exists: true. Next steps
- Concepts: projects, paths, public vs private, and the key model.
- Webhooks: get notified when your documents change.
- Browse the other SDKs