What is Auth and Capture?

An auth and capture transaction is suitable for credit-based purchases with a delay involved. An example is an e-commerce sale that involves shipping after a few days.

The payment is authed at the time of purchase and captured at the time of shipping.

  • Authorize: authorize a subscriber’s credit card/ account for a period (expires after 30 days)

    • check with the subscriber’s bank to see if the credit card is legitimate
    • has sufficient funds for the amount authorized.
      If the subscriber’s bank approves, a hold is placed on the funds in the subscriber’s account but no money has moved, yet.
  • Capture: To move money from the subscriber’s account, you have to issue a capture request on the original authorization to collect (“capture”) the funds.

  • Cancel: If you choose not to capture the funds from the subscriber’s account, you can explicitly cancel the authorization to release the hold on those funds.

References

https://docs.recurly.com/docs/auth-and-capture

Strategy Pattern in Golang

Introduction

The strategy is a behavior pattern. It fits where multiple choices for an interface are available and the design would allow switching them dynamically.

Conditions

  • A set of choices with similarity in the interface
  • Dynamic update of a choice

Example

  1. A cache with evictions
    • Multiple eviction algorithms
    • Cache could switch to a different algorithm dynamically
  2. A duck type has a variety of flying behaviors. A duck can fly very fast, slow and no-fly.

Implementation

Define what a duck is.

// duck_type.go

package main

type duck struct {
	flyBehavior
}

Define fly behavior

// fly_behavior.go

package main

type flyBehavior interface {
	fly()
	nofly()
}

Define the fast duck fly behavior

//fast_duck.go

package main

import "fmt"

type duckF18 struct {
}

func (d *duckF18) fly() {
	fmt.Printf("%+v\n", "flying like a F18")
}

func (d *duckF18) nofly() {
	fmt.Printf("%+v\n", "not implemented")
}

Define no fly behavior

// nofly_duck.go

package main

import "fmt"

type duckNofly struct {
}

func (d *duckNofly) fly() {
	fmt.Printf("%+v\n", "not implemented")
}

func (d *duckNofly) nofly() {
	fmt.Printf("%+v\n", "no flying")
}

// main.go

package main

func createNewDuck(f flyBehavior) *duck {
	return &duck{
		flyBehavior: f,
	}
}

func (d *duck) setFlyBehavior(f flyBehavior) {
	d.flyBehavior = f
}

func main() {
	// f18 duck
	aDuck := createNewDuck(&duckF18{})
	aDuck.flyBehavior.fly()

    // duck switches to no fly
	aDuck.setFlyBehavior(&duckNofly{})
	aDuck.flyBehavior.fly()
}

References

  1. https://golangbyexample.com/strategy-design-pattern-golang/
  2. https://www.youtube.com/watch?v=9uDFHTWCKkQ

golang: How to Add Better Context to Errors

golang: How to Add Better Context to Errors

There are at least three ways to add more context to errors.

  1. fmt.Errorf
  2. errors package
  3. zap library
package main

import (
	"errors"
	"fmt"

	werr "github.com/pkg/errors"
	"go.uber.org/zap"
)

// 1. wraps with a message
func wrap(e error) error {
	return fmt.Errorf("another layer - %w", e)
}

// 2. wraps with callstack and message
func betterWrap(e error) error {
	return werr.Wrap(e, "a better layer")
}

// 3. wraps with the first callstack frame
func zapLogger(e error) {
	logger, _ := zap.NewProduction()
	defer logger.Sync()
	logger.Info("failed to fetch URL",
		// Structured context as strongly typed Field values.
		zap.Error(e))
}

func main() {
	e := errors.New("a test err")

	fmt.Printf("err= %+v\n", wrap(e))
	fmt.Printf("%+v\n", betterWrap(e))
	zapLogger(e)
}

Execution

 $ go run err_context.go

fmt.errorf

err= another layer - a test err

errors package

a test err
a better layer
main.betterWrap
        /Users/xxx/go-code/blog/err/err_context.go:18
main.main
        /Users/xxx/go-code/blog/err/err_context.go:35
runtime.main
        /Users/xxx/.goenv/versions/1.14.0/src/runtime/proc.go:203
runtime.goexit
        /Users/xxx/.goenv/versions/1.14.0/src/runtime/asm_amd64.s:1373

zap

{"level":"info","ts":1604374256.270431,"caller":"err/err_context.go:25",
"msg":"failed to fetch URL","error":"a test err"}

Conclusion

I like the errors package the most. It has a relevant context to troubleshoot a problem.

Get a Free Public Web Address

Get a Free Public Web Address

What is ngrok?

Ngrok exposes local servers behind NATs and firewalls to the public internet over secure tunnels.

Run personal cloud services from your home

Demo websites without deploying

Build webhook consumers on your dev machine

Test mobile apps connected to your locally running backend

Stable addresses for your connected devices that are deployed in the field

https://ngrok.com/product

This product solves a critical problem in developing solution that require a third party service. I think we can mock an endpoint with a local server. Also, we can export our local server to the world 🙂

How to Check nil Interface in Golang?

It’s not a good idea to check an interface for nil.

Try the following code:

type user interface{}
type staff struct{}

func compareNil() {
    var generic user
	generic = nil

    // works as expected
	fmt.Printf("value=%v type=%T (generic==nil)=%v\n", generic, generic, generic == nil)

    generic = (*staff)(nil)

    // fails my expectation
	fmt.Printf("value=%v type=%T (generic==nil)=%v\n", generic, generic, generic == nil)
}

go playground: https://play.golang.org/p/7J9DeIjgNia

Output
value=<nil> type=*main.staff (generic==nil)=false
value=<nil> type=<nil> (generic==nil)=true
Why interface check for nil is special

An interface is a tuple of [Value, Type]. The nil interface is a tuple [nil, nil]. However, the above code is an interface containing [nil, *main.staff] which is not nil.

We can check for nil as follows:

func isNil(i interface{}) bool {                        
    return i == nil || reflect.ValueOf(i).IsNil() 
}

Here i==nil means i has [nil, nil] or has a nil value in [nil, *main.staff].

But if the interface points to a type that has no Nil value:

s := "hello"
generic = s
fmt.Printf("value=%v type=%T type=%v\n", generic, generic, reflect.ValueOf(generic).IsNil())

The code panics:

panic: reflect: call of reflect.Value.IsNil on string Value

goroutine 1 [running]:
reflect.Value.IsNil(...)
        /Users/xxx/.goenv/versions/1.14.0/src/reflect/value.go:1063
main.compareNil()
        /Users/xxx/go/1.14.0/src/mygo/interfaces/interfaces.go:48 +0x3b1
main.main()
        /Users/xxx/go/1.14.0/src/mygo/interfaces/interfaces.go:29 +0x142
exit status 2

Conclusion

The safest way to compare nil interfaces is switch on various types the interface can assume. Never check as myinterface == nil.

References

Google Auth App Not Working: Quits on Launch on iOS

Google Auth App Not Working: Quits on Launch on iOS

After upgrading iOS, the Auth app started exiting on launch.

Solution

  • Go to Settings->General->Storage
  • Now find Google Auth App in the list
  • Offload App. It retains all your data.
  • Install again. It could work now!

json: cannot unmarshal object into Go struct field

Problem

json: cannot unmarshal object into Go struct field

Code

package main

import (
	"encoding/json"
	"fmt"
)

// DTO object
type mould struct {
	Particle tiny
}

type tiny interface {
	GetName() string
}

// Implement the interface
type speck struct {
	Name string `json:"name"`
}

func (s *speck) GetName() string {
	return s.Name
}

// Constructor
func NewSpeck(name string) tiny {
	return &speck{
		Name: name,
	}
}

//
func main() {
	dirt := NewSpeck("space")

	brown := &mould{}
	brown.Particle = dirt
	brownBytes, err := json.Marshal(brown)

	if err != nil {
		panic("marshal error")
	}

	brownLike := &mould{} // unmarshal has no "idea" of how to unpack!
	err = json.Unmarshal(brownBytes, &brownLike)
	if err != nil {
		panic("unmarshal err=%+v\n", err)
		return
	}
}

Go Playground Link

The error is:

go run unmarshal_interface.go
panic: json: cannot unmarshal object into Go struct field mould.Particle of type main.tiny

The problem with code is the inability of Go runtime to get target struct for unmarshaling.

Unmarshal essentially copies the byte array to a struct type. However, in the case of the unmarshal of the type tiny, runtime could not find any destination struct. The interface in Go just has behavior, not types.

Solutions

  1. Easy! Don’t return interface in a function. 🙂
  2. Help the runtime and add some info on destination struct.
    // solution
    brownLike2 := &mould{}
    brownLike2.Particle = &speck{} // Now unmarshal "knows" how to unpack the byte array!
    
    err = json.Unmarshal(brownBytes, &brownLike2)
    fmt.Printf("brownLike2=%#v err=%+v\n", brownLike2.Particle.GetName(), err)
    

Refernces

Written with StackEdit.

Quick Read on UTF-8 in Golang

Raw Strings

we create a “raw string”, enclosed by back quotes, so it can contain only literal text.
Regular strings, enclosed by double quotes, can contain escape sequences as we showed above.

package main

import (
	"fmt"
)

func main() {

	fmt.Println(`go\\n`)
	fmt.Println("escapedGo\\n")
}

Output

go\\n
escapedGo\n
  • Raw string is always UTF-8 because it is part of the Go source code which is always UTF-8.
  • strings can contain arbitrary bytes, but when constructed from string literals, those bytes are (almost always) UTF-8.

Rune

  • 32 bit integer
  • Used to represent a UTF-8 code point of upto 4 bytes
  • Example
    • The Unicode code point U+0061 is the lower case Latin letter ‘A’: a.
    • There are at least two ways to write letter à:
      • Code point of à is U+00E0
      • Code point of grave accent (U+0300) + U+00E0

So there are different byte sequences for the same character!

How Golang handle literals?

  • A literal is a valid UTF-8 sequence.
  • It is always true for a literal
    `aLiteral`
    

Strings are built from bytes so indexing them yields bytes, not characters. A string might not even hold characters.

References