Introduction
⚡️ SharePoint authentication, HTTP client & fluent API wrapper for Go (Golang)

Main features

  • Unattended authentication using different strategies.
  • Fluent API syntax for SharePoint object model.
  • Simplified API consumption (REST, CSOM, SOAP, etc.).
  • SharePoint-aware embedded features (retries, header presets, error handling).

Supported SharePoint versions

  • SharePoint Online (SPO).
  • On-Premises (2019/2016/2013).

Supported auth strategies

Installation

go get github.com/koltyakov/gosip

Usage insights

Understand SharePoint environment type and authentication strategy

Let's assume it's SharePoint Online and Add-In Only permissions. Then strategy "github.com/koltyakov/gosip/auth/addin" sub package should be used.
package main
import (
"github.com/koltyakov/gosip"
"github.com/koltyakov/gosip/api"
strategy "github.com/koltyakov/gosip/auth/addin"
)

Initiate authentication object

auth := &strategy.AuthCnfg{
SiteURL: os.Getenv("SPAUTH_SITEURL"),
ClientID: os.Getenv("SPAUTH_CLIENTID"),
ClientSecret: os.Getenv("SPAUTH_CLIENTSECRET"),
}
AuthCnfg's from different strategies contains different options relevant for a specified auth type.
The authentication options can be provided explicitly or can be read from a configuration file (see more).
configPath := "./config/private.json"
auth := &strategy.AuthCnfg{}
err := auth.ReadConfig(configPath)
if err != nil {
fmt.Printf("Unable to get config: %v\n", err)
return
}

Bind auth client with Fluent API

client := &gosip.SPClient{AuthCnfg: auth}
sp := api.NewSP(client)
res, err := sp.Web().Select("Title").Get()
if err != nil {
fmt.Println(err)
}
fmt.Printf("%s\n", res.Data().Title)

Usage samples

Fluent API client

Provides a simple way of constructing API endpoint calls with IntelliSense and chainable syntax.
package main
import (
"encoding/json"
"fmt"
"log"
"github.com/koltyakov/gosip"
"github.com/koltyakov/gosip/api"
strategy "github.com/koltyakov/gosip/auth/addin"
)
func main() {
// Getting auth params and client
client, err := getAuthClient()
if err != nil {
log.Fatalln(err)
}
// Binding SharePoint API
sp := api.NewSP(client)
// Custom headers
headers := map[string]string{
"Accept": "application/json;odata=minimalmetadata",
"Accept-Language": "de-DE,de;q=0.9",
}
config := &api.RequestConfig{Headers: headers}
// Chainable request sample
data, err := sp.Conf(config).Web().Lists().Select("Id,Title").Get()
if err != nil {
log.Fatalln(err)
}
// Response object unmarshalling
// (struct depends on OData mode and API method)
res := &struct {
Value []struct {
ID string `json:"Id"`
Title string `json:"Title"`
} `json:"value"`
}{}
if err := json.Unmarshal(data, &res); err != nil {
log.Fatalf("unable to parse the response: %v", err)
}
for _, list := range res.Value {
fmt.Printf("%+v\n", list)
}
}
func getAuthClient() (*gosip.SPClient, error) {
configPath := "./config/private.spo-addin.json" // <- file with creds
auth := &strategy.AuthCnfg{}
if err := auth.ReadConfig(configPath); err != nil {
return nil, fmt.Errorf("unable to get config: %v", err)
}
return &gosip.SPClient{AuthCnfg: auth}, nil
}

Generic HTTP-client helper

Provides generic GET/POST helpers for REST operations, reducing amount of http.NewRequest scaffolded code, can be used for custom or not covered with a Fluent API endpoints.
package main
import (
"fmt"
"log"
"github.com/koltyakov/gosip"
"github.com/koltyakov/gosip/api"
strategy "github.com/koltyakov/gosip/auth/ntlm"
)
func main() {
configPath := "./config/private.ntlm.json"
auth := &strategy.AuthCnfg{}
if err := auth.ReadConfig(configPath); err != nil {
log.Fatalf("unable to get config: %v\n", err)
}
sp := api.NewHTTPClient(&gosip.SPClient{AuthCnfg: auth})
endpoint := auth.GetSiteURL() + "/_api/web?$select=Title"
data, err := sp.Get(endpoint, nil)
if err != nil {
log.Fatalf("%v\n", err)
}
// sp.Post(endpoint, []byte(body), nil) // generic POST
// generic DELETE helper crafts "X-Http-Method"="DELETE" header
// sp.Delete(endpoint, nil)
// generic UPDATE helper crafts "X-Http-Method"="MERGE" header
// sp.Update(endpoint, nil)
// CSOM helper (client.svc/ProcessQuery)
// sp.ProcessQuery(endpoint, []byte(body))
fmt.Printf("response: %s\n", data)
}

Low-level HTTP-client usage

Low-lever SharePoint-aware HTTP client from github.com/koltyakov/gosip package for custom or not covered with a Fluent API client endpoints with granular control for HTTP request, response, and http.Client parameters. Used internally but almost never required in a consumer code.
client := &gosip.SPClient{AuthCnfg: auth}
var req *http.Request
// Initiate API request
// ...
resp, err := client.Execute(req)
if err != nil {
fmt.Printf("Unable to request api: %v", err)
return
}
SPClient has Execute method which is a wrapper function injecting SharePoint authentication and ending up calling http.Client's Do method.

Reference

Many auth flows have been "copied" from node-sp-auth library (used as a blueprint), which we intensively use in Node.js ecosystem for years.
Fluent API and wrapper syntax are inspired by PnPjs which is also the first-class citizen on almost all our Node.js and front-end projects with SharePoint involved.

License

Last modified 1yr ago
Export as PDF
Copy link
On this page
Main features
Supported SharePoint versions
Supported auth strategies
Installation
Usage insights
Understand SharePoint environment type and authentication strategy
Initiate authentication object
Bind auth client with Fluent API
Usage samples
Fluent API client
Generic HTTP-client helper
Low-level HTTP-client usage
Reference
License