[FLINK-18810][sdk] Document Golang SDK

This closes #250
diff --git a/docs/content/docs/io-module/flink-connectors.md b/docs/content/docs/io-module/flink-connectors.md
index b065f78..330cc4a 100644
--- a/docs/content/docs/io-module/flink-connectors.md
+++ b/docs/content/docs/io-module/flink-connectors.md
@@ -162,4 +162,37 @@
 }
 ```
 {{< /tab >}}
+{{< tab "Golang" >}}
+```go
+import (
+	"fmt"
+	"github.com/apache/flink-statefun/statefun-sdk-go/v3/pkg/statefun"
+    "time"
+)
+
+func (g *Greeter) Invoke(ctx statefun.Context, message: statefun.Message) error {
+    if !message.Is(UserType) {
+        return fmt.Errorf("unknown type %s", message.ValueTypeName())
+    }
+
+    var user User
+    _ = user.As(UserType, &user)
+
+    storage = context.Storage()
+
+    var seen int32
+    storage.Get(g.SeenCount, &seen)
+    seen += 1
+    storage.Set(g.SeenCount, seen)
+
+	ctx.SendEgress(&statefun.GenericEgressBuilder{
+		Target: statefun.TypeNameFrom("com.example/greets"),
+		Value:  fmt.Sprintf("Hello %s for the %s-th time!", user.Name, count),
+		ValueType: statefun.StringType,
+	})
+
+    return nil
+}
+```
+{{< /tab >}}
 {{< /tabs >}}
\ No newline at end of file
diff --git a/docs/content/docs/sdk/golang.md b/docs/content/docs/sdk/golang.md
new file mode 100644
index 0000000..9525d77
--- /dev/null
+++ b/docs/content/docs/sdk/golang.md
@@ -0,0 +1,362 @@
+---
+title: Golang
+weight: 4
+type: docs
+---
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+# Golang SDK
+
+Stateful functions are the building blocks of applications; they are atomic units of isolation, distribution, and persistence.
+As objects, they encapsulate the state of a single entity (e.g., a specific user, device, or session) and encode its behavior.
+Stateful functions can interact with each other, and external systems, through message passing.
+
+To get started, add the Golang SDK as a dependency to your application.
+
+{{< selectable >}}
+```
+require github.com/apache/flink-statefun/statefun-sdk-go
+```
+{{< /selectable >}}
+
+## Defining A Stateful Function
+
+A stateful function is any class that implements the `StatefulFunction` interface.
+In the following example, a `StatefulFunction` maintains a count for every user
+of an application, emitting a customized greeting.
+
+```go
+import (
+	"fmt"
+	"github.com/apache/flink-statefun/statefun-sdk-go/v3/pkg/statefun"
+)
+
+type Greeter struct {
+	SeenCount statefun.ValueSpec
+}
+
+func (g *Greeter) Invoke(ctx statefun.Context, message statefun.Message) error {
+	if !message.Is(statefun.StringType) {
+		return fmt.Errorf("unexpected message type %s", message.ValueTypeName())
+	}
+
+	var name string
+	_ = message.As(statefun.StringType, &name)
+
+	storage := ctx.Storage()
+
+	var count int32
+	storage.Get(g.SeenCount, &count)
+
+	count += 1
+
+	storage.Set(g.SeenCount, count)
+
+	ctx.Send(statefun.MessageBuilder{
+		Target: statefun.Address{
+			FunctionType: statefun.TypeNameFrom("com.example.fns/inbox"),
+			Id:           name,
+		},
+		Value: fmt.Sprintf("Hello %s for the %dth time!", name, count),
+	})
+
+	return nil
+}
+```
+
+This code declares a greeter function that will be [registered](#serving-functions) under the logical type name `com.example.fns/greeter`. Type names must take the form `<namesapce>/<name>`.
+It contains a single `ValueSpec`, which is implicitly scoped to the current address and stores an int32.
+
+Alternatively, a stateful function can be defined as a function pointer.
+
+```go
+func greeter(ctx statefun.Context, message statefun.Message) error {
+    panic("Implement me!")
+}
+```
+
+Every time a message is sent a greeter instance, it is interpreted as a `string` representing the users name.
+Both messages and state are strongly typed - either one of the default [built-in types]({{< ref "docs/sdk/appendix#types" >}}) - or a [custom type](#types).
+
+The function finally builds a custom greeting for the user.
+The number of times that particular user has been seen so far is queried from the state store and updated
+and the greeting is sent to the user's inbox (another function type). 
+
+## Types
+
+Stateful Functions strongly types all messages and state values. 
+Because they run in a distributed manner and state values are persisted to stable storage, Stateful Functions aims to provide efficient and easy to use serializers. 
+
+Out of the box, all SDKs offer a set of highly optimized serializers for common primitive types; boolean, numerics, and strings.
+Additionally, users are encouraged to plug-in custom types to model more complex data structures. 
+
+In the [example above](#defining-a-stateful-function), the greeter function consumes a simple `string`.
+Often, functions need to consume more complex types containing several fields.
+
+By defining a custom type, this object can be passed transparently between functions and stored in state.
+And because the type is tied to a logical typename, instead of the physical golang function or struct, it can be passed to functions written in other language SDKs. 
+
+```go
+import (
+	"github.com/apache/flink-statefun/statefun-sdk-go/v3/pkg/statefun"
+)
+
+type User struct {
+	Name          string
+	FavoriteColor string
+}
+
+UserType = MakeJsonType(statefun.TypeNameFrom("com.example/User"))
+```
+
+Alternatively, you can implement the `SimpleType` interface for full control over serialization.
+
+## State
+
+Stateful Functions treats state as a first class citizen and so all functions can easily define state that is automatically made fault tolerant by the runtime.
+State declaration is as simple as defining one or more `ValueSpec`s describing your state values.
+Value specifications are defined with a unique (to the function) name and [type](#types).
+
+{{< hint info >}}
+All value specifications must be eagerly registered in the `StatefulFuctions` decorator when declaring the function.
+{{< /hint >}}
+
+```go
+// Value specification for a state named `seen` 
+// with the primitive integer type
+statefun.ValueSpec {
+    Name:      "seen_count",
+    ValueType: statefun.Int32Type,
+}
+
+// Value specification with a custom type
+statefun.ValueSpec {
+    Name:      "user",
+    ValueType: UserType,
+}
+```
+
+At runtime, functions can `get`, `set`, and `remove` state values scoped to the address of the current message.
+The value spec is scoped within the `Greeter` struct for convenience.
+
+```go
+type Greeter struct {
+	SeenCount statefun.ValueSpec
+}
+
+func (g *Greeter) Invoke(ctx statefun.Context, message statefun.Message) error {
+    storage := ctx.Storage()
+
+    // Read the current value of the state
+    // or zero value if no value is set
+    var count int32
+    storage.Get(g.SeenCount, &count)
+
+    count += 1
+
+    // Update the state which will
+    // be made persistent by the runtime
+    storage.Set(g.SeenCount, count)
+
+    log.Printf("the current count is %s", count)
+    
+    if count > 10 {
+        // Delete the state value
+        storage.Remove(g.SeenCount)
+    }
+
+    return nil
+}
+```
+
+### State Expiration
+
+By default, state values are persisted until manually `deleted`ed by the user.
+Optionally, they may be configured to expire and be automatically deleted after a specified duration.
+
+```go
+import "time"
+
+// Value specification that will automatically
+// delete the value if the function instance goes 
+// more than 30 minutes without being called
+statefun.ValueSpec {
+    Name:      "seen_count",
+    ValueType: statefun.Int32Type,
+    Expiration: ExpireAfterCall(time.Duration(30) * time.Minutes)
+}
+
+// Value specification that will automatically
+// delete the value if it goes more than 30 minutes
+// without being written
+statefun.ValueSpec {
+    Name:      "seen_count",
+    ValueType: statefun.Int32Type,
+    Expiration: ExpireAfterWrite(time.Duration(30) * time.Minutes)
+}
+```
+
+## Sending Delayed Messages
+
+Functions can send messages on a delay so that they will arrive after some duration.
+They may even send themselves delayed messages that can serve as a callback.
+The delayed message is non-blocking, so functions will continue to process records between when a delayed message is sent and received.
+Additionally, they are fault-tolerant and never lost, even when recovering from failure. 
+
+This example sends a response back to the calling function after a 30 minute delay.
+
+```go
+import (
+    "fmt"
+    "github.com/apache/flink-statefun/statefun-sdk-go/v3/pkg/statefun"
+    "time"
+)
+
+func delayed(ctx statefun.Context, message: statefun.Message) error {
+    if ctx.Caller() == nil {
+        fmt.Println("message has no known caller meaning it was sent directly from an ingress")
+    }
+
+    ctx.SendAfter(
+        time.Duration(30) * time.Minutes,
+        MessageBuilder {
+            Target: ctx.Caller(),
+            Value: "Hello from the future!",
+        }
+    )
+
+    return nil
+}
+```
+
+## Egress
+
+Functions can message other stateful functions and egresses, exit points for sending messages to the outside world.
+As with other messages, egress messages are always well-typed. 
+Additionally, they contain metadata pertinent to the specific egress type.
+
+{{< tabs "egress" >}}
+{{< tab "Apache Kafka" >}}
+```go
+import (
+    "fmt"
+    "github.com/apache/flink-statefun/statefun-sdk-go/v3/pkg/statefun"
+    "time"
+)
+
+func (g *Greeter) Invoke(ctx statefun.Context, message: statefun.Message) error {
+    if !message.Is(UserType) {
+        return fmt.Errorf("unknown type %s", message.ValueTypeName())
+    }
+
+    var user User
+    _ = user.As(UserType, &user)
+
+    storage = context.Storage()
+
+    var seen int32
+    storage.Get(g.SeenCount, &seen)
+    seen += 1
+    storage.Set(g.SeenCount, seen)
+
+	ctx.SendEgress(&statefun.KafkaEgressBuilder{
+		Target: statefun.TypeNameFrom("com.example/greets"),
+		Topic:  "greetings",
+		Key:    user.Name,
+		Value:  fmt.Sprintf("Hello %s for the %s-th time!", user.Name, count),
+	})
+
+    return nil
+}
+```
+{{< /tab >}}
+{{< tab "Amazon Kinesis" >}}
+```go
+import (
+    "fmt"
+    "github.com/apache/flink-statefun/statefun-sdk-go/v3/pkg/statefun"
+    "time"
+)
+
+func (g *Greeter) Invoke(ctx statefun.Context, message: statefun.Message) error {
+    if !message.Is(UserType) {
+        return fmt.Errorf("unknown type %s", message.ValueTypeName())
+    }
+
+    var user User
+    _ = user.As(UserType, &user)
+
+    storage = context.Storage()
+
+    var seen int32
+    storage.Get(g.SeenCount, &seen)
+    seen += 1
+    storage.Set(g.SeenCount, seen)
+
+	ctx.SendEgress(&statefun.KinesisEgressBuilder{
+		Target: statefun.TypeNameFrom("com.example/greets"),
+		Stream:  "greetings",
+		PartitionKey:    user.Name,
+		Value:  fmt.Sprintf("Hello %s for the %s-th time!", user.Name, count),
+	})
+
+    return nil
+}
+```
+{{< /tab >}}
+{{< /tabs >}}
+
+## Serving Functions
+
+The Golang SDK ships with a ``RequestReplyHandler`` that is a standard http `Handler` and automatically dispatches function calls based on RESTful HTTP ``POSTS``.
+The handler is created using the `StatefulFunctionsBuilder` and is composed of all the stateful functions bound to the system.
+
+This example create a handler for greeter function and exposes it using the standard golang web framework. 
+
+```go
+import (
+    "fmt"
+    "github.com/apache/flink-statefun/statefun-sdk-go/v3/pkg/statefun"
+    "net/http"
+)
+
+func main() {
+	greeter := &Greeter{
+		SeenCount: statefun.ValueSpec{
+			Name:      "seen_count",
+			ValueType: statefun.Int32Type,
+		},
+	}
+
+	builder := statefun.StatefulFunctionsBuilder()
+	_ = builder.WithSpec(statefun.StatefulFunctionSpec{
+		FunctionType: statefun.TypeNameFrom("com.example.fns/greeter"),
+		States:       []statefun.ValueSpec{greeter.SeenCount},
+		Function:     greeter,
+	})
+
+	http.Handle("/statefun", builder.AsHandler())
+	_ = http.ListenAndServe(":8000", nil)
+}
+```
+
+## Next Steps
+
+Keep learning with information on setting up [I/O modules]({{< ref "docs/io-module/overview" >}}) and configuring the [Stateful Functions runtime]({{< ref "docs/deployment/overview" >}}).
\ No newline at end of file