LogoLogo
GoDocGitHub
  • Introduction
  • FAQ
  • Authentication strategies
    • Overview
    • Strategies
      • Azure Certificate Auth
      • Azure Creds Auth
      • Azure Env-based Auth
      • Azure Device Flow
      • SAML Auth
      • AddIn Only
        • Configuration
      • NTLM Auth
      • NTLM (alternative)
      • On-Demand Auth
      • ADFS Auth
      • FBA Auth
      • TMG Auth
      • Anonymous
    • Dynamic auth
    • Custom Auth
  • SharePoint client
    • HTTP Client
    • Fluent API
    • Hooks
    • Retries
    • Context
  • Samples
    • Library Initiation
    • Basic CRUD
    • Documents
    • Chunk upload
    • Permissions
    • Groups & Users
    • Search API
    • User Profiles
    • Change API
    • Attachments
    • Record Management
    • Sending Emails
    • Property Bags
    • Recycle Bin
    • Feature management
    • Advanced item requests
    • Advanced add/update
    • Unmarshaling responses
  • Sandbox
    • Overview
  • Utilities
    • Headers presets
    • Cpass
    • Compatibility matrix
  • Contributing
    • Overview
    • Testing
Powered by GitBook
On this page

Was this helpful?

Edit on GitHub
Export as PDF
  1. Samples

Unmarshaling responses

Parsing complex responses

Gosip Fluent API tries providing strongly typed responses objects, but in most situations, it's not possible as there are many factors reshaping a response JSON body.

By defining different OData modes (Verbose, Minimalmetadata, Nometadata) within the Accept headers SharePoint REST API returns not only data of different details but also data in different forms payload shape-terms. Which can lead to runtime errors.

We're are not forcing to use one specific OData mode only (e.g. Minimalmetadata) as this would prevent support of some old SharePoint versions (2013) without additional server-side configurations, we have responses normalisation methods which reshape JSONs from the API to the close or identical form no matter the OData mode is.

Let's take a look at the example:

package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/koltyakov/gosip"
	"github.com/koltyakov/gosip/api"
	strategy "github.com/koltyakov/gosip/auth/saml"
)

func main() {
	// Binding auth & API client
	configPath := "./config/private.saml.json"
	authCnfg := &strategy.AuthCnfg{}
	if err := authCnfg.ReadConfig(configPath); err != nil {
		log.Fatalf("unable to get config: %v", err)
	}
	client := &gosip.SPClient{AuthCnfg: authCnfg}
	sp := api.NewSP(client)

	// Getting items from a custom list
	list := sp.Web().GetList("Lists/MyList")
	data, err := list.Items().Select("Id,CustomField").Get()
	if err != nil {
		log.Fatalln(err)
	}

	// Define a stuct or map[string]interface{} for unmarshalling
	items := []*struct {
		ID     int    `json:"Id"`
		Custom string `json:"CustomField"`
	}{}

	// .Normalized() method aligns responses between different OData modes
	if err := json.Unmarshal(data.Normalized(), &items); err != nil {
		log.Fatalf("unable to parse the response: %v", err)
	}

	for _, item := range items {
		fmt.Printf("%+v\n", item)
	}

}

Almost any API byte array response has extension methods, such as .Data() and .Normalize(). The Data method uses predefined generic API entity items unmarshaling, it can be useful for the OOTB entities, e.g. Webs, Groups, Lists, to name just a few. But won't allow getting custom item values for example.

When it comes to custom responses, you have to unmarshal by your own, however, Gosip also helps with this by providing normalization methods.

Let's compare responses in a bit much details:

// "Accepts": "application/json;odata=verbose"
{
  "d": {
    "results": [
      {
        "Id": 134,
        "CustomField": "CustomValue",
        "ID": 134,
        // ...
      }
    ]
  }
}

// "Accepts": "application/json;odata=minimalmetadata"
{
  "value": [
    {
      "Id": 134,
      "CustomField": "CustomValue",
      "ID": 134,
      // ...
    }
  ],
  // ...
}

// "Accepts": "application/json;odata=nometadata"
{"value":[{"Id":134,"CustomField":"CustomValue","ID":134}]}

As can be seen, there is a great difference in Verbose and Minimal/No metadata modes in shape-terms. The difference is mode dramatic when complex data fields come into play.

After normalization, responses shape is reduced to the following:

[
  {
    "CustomField": "CustomValue",
    "ID": 134,
    "Id": 134,
    // ...
  }
]

This makes unmarshalling in times simpler and reduce potential errors after deciding changing OData mode globally.

PreviousAdvanced add/updateNextOverview

Last updated 5 years ago

Was this helpful?

Open on GitHub