feat: upgrade and gotsrpc docs WIP

This commit is contained in:
Jan Halfar 2023-04-20 14:53:23 +02:00
parent 3242ecbcaa
commit e7ff60579e
23 changed files with 8239 additions and 755 deletions

View File

@ -1,4 +1,4 @@
# Introduction
# Gocontentful
## What is Contentful

View File

@ -1,7 +1,4 @@
---
sidebar_position: 0
---
# Intro
# CMS
The foomo team has extensive experience with a wide range of CMS systems. Our long journey in the field has brought us very close to the https://jamstack.org . We almost exclusively work with https://app.contentful.com/ but we are watching others like https://www.stripe.com/ very closely.

View File

@ -1,6 +0,0 @@
# gotsrpc
https://github.com/foomo/gotsrpc
Since we are using go when writing

View File

@ -0,0 +1,5 @@
# Getting started
- install `gotsrpc` [cli](cli)
- clone and play with the [playground](playground)
- follow [workflow](workflow) instructions

View File

@ -0,0 +1,15 @@
# Workflow
## Initial setup in a project
- define a central place for your Go service interface definitions
- define a central place where your TypeScript client code will be generated to
- create one central [`gotsrpc.yaml`](gotsrpc.yaml)
- implement a TypeScript [`transport`](transport) for your project
## Per service
1. define [service interfaces](service-interfaces) in Go
2. configure code generation in [`gotsrpc.yaml`](gotsrpc.yaml)
3. generate service proxies and client with [`gotsrpc` cli](cli)
4. go to 1.

View File

@ -0,0 +1,44 @@
# Service Interfaces
`Gotsrpc` services are defined in Go. Visit the [playground](playground)
## Interface definitions and value objects
All `gotsrpc` service definitions should be in a central place separated from their respective implementations.
### Definition of a service interface
Service interfaces for gotsrpc services are plain Go interfaces.
```go
type Service interface {
HelloWorld(name string) string
}
```
### Special handling of http request arguments
Despite the fact, that `gostrpc` is not RESTful it is possible and encouraged to access the underlying incoming [`w http.ResponseWriter`](https://pkg.go.dev/net/http#ResponseWriter) and [`r *http.Request`](https://pkg.go.dev/net/http#Request) arguments like in a [`http.HandlerFunc`](https://pkg.go.dev/net/http#HandlerFunc) for use cases like:
- http request headers eg to implement access tokens
- http request and response headers for cookie handling
- accessing [r.Context()](https://pkg.go.dev/net/http#Request.Context) for proper handling of context handling in the given request context
- ...
Service interface with http.HandlerFunc arguments
```go
type Service interface {
HelloWorld(w http.ResponseWriter, r *http.Request, name string) string
}
```
In the generated client code the interface will not change. Accessing headers, cookies etc is handled in your projects [client and transport](client-transport)
:::note
**arguments and return values have to be serializable**
All arguments and return values will be marshalled typically as [JSON](https://www.json.org)
[Also see protocol](protocol#encoding--marshalling)
:::

View File

@ -0,0 +1,89 @@
# Value Objects
Typically value objects will be serialized / marshalled as JSON. Please refer to this documentation:
[https://pkg.go.dev/encoding/json#Marshal](https://pkg.go.dev/encoding/json#Marshal)
## Scalar types
### Supported in Go and TypeScript
| Go | TypeScript |
| ------ | ---------- |
| string | string |
| bool | boolean |
### Numerics / numbers
| Go | TypeScript |
| -------------------------------------- | ---------- |
| int, int8, int16, float32, float64 ... | number |
### Type Aliases
Go
```go
type Greeting string
```
TypeScript
```typescript
type Greeting = string;
```
## Enumerations
Go does not support enumerations, but `gotsrpc` will translate constants to TypeScripts enums:
Go
```go
type Pet string
const (
Cat Pet = "cat"
Dog Pet = "dog"
Fish Pet = "fish"
)
type SeatCount int
const (
TwoSeats SeatCount = 2
FiveSeats SeatCount = 5
SevenSeats SeatCount = 7
)
```
TypeScript
```typescript
export enum Pet {
Cat = "cat",
Dog = "dog",
Fish = "fish",
}
export enum SeatCount {
FiveSeats = 5,
SevenSeats = 7,
TwoSeats = 2,
}
```
## Structs / Interfaces
```go
type Car struct {
}
```
```typescript
interface Car {
}
```
## Slices / Arrays
## Maps / Records

View File

@ -0,0 +1,2 @@
# Errors

View File

@ -0,0 +1,30 @@
# cli
Command line program to generate gotsrpc clients and service proxies.
## Installation
Downloads are available here: https://github.com/foomo/gotsrpc/releases
Homebrew:
```shell
brew install foomo/gotsrpc/gotsrpc
```
## Usage
To run a code generation with `gosrpc` run
```shell
gotsrpc gotsrpc.yaml
```
- the referenced Go code has to compile
- mappings for all used packages must be configured
If things do not work as expected - carefully read the output.
:::caution
Previously generated code will be overwritten and potentially obsolete files will not be deleted - please add a clean to your build
:::

View File

@ -0,0 +1,29 @@
# TypeScript client transport
## Client transport implementation
Every project has it's custom transport implementation. It typically is a good place for:
- http header handling for requests and responses eg adding trace ids
- custom handling of client vs server side transports (browser vs Node.js)
- central error handling
- client activity tracking
```typescript reference title="example transport"
https://github.com/foomo/gotsrpc-playground/blob/main/client/services/transport.ts#L1-L17
```
## Client client construction
Client construction is also project specific.
- special handling of server side endpoints
- adding transport middlewares
- passing through client request headers and cookies on the server side
This is a minimal client side client constructor:
```typescript reference title="example client construction"
https://github.com/foomo/gotsrpc-playground/blob/main/client/services/transport.ts#L18-L29
```

View File

@ -0,0 +1,39 @@
# Hello, World!
Enter your name in a form, send it to the server and get a greeting in return.
[http://localhost:8080/hello-world](http://localhost:8080/hello-world)
## Go service
Service interface defintion
```go reference title="server/services/helloworld/service.go"
https://github.com/foomo/gotsrpc-playground/blob/main/server/services/helloworld/service.go
```
Service implementation
```go reference title="server/services/helloworld/service.go"
https://github.com/foomo/gotsrpc-playground/blob/main/server/server/helloworld.go
```
Service proxy instantiation
```go reference title="server/main.go"
https://github.com/foomo/gotsrpc-playground/blob/main/server/main.go#L37
```
Using the service proxy as a http handler
```go reference title="server/main.go"
https://github.com/foomo/gotsrpc-playground/blob/main/server/main.go#L59
```
## Next.js TypeScript client
Using the client in a Next.js page
```typescript reference title="client/pages/hello-world.tsx"
https://github.com/foomo/gotsrpc-playground/blob/main/client/pages/hello-world.tsx#L8-L21
```

View File

@ -0,0 +1,25 @@
# Wheel of Fortune
Spin the Wheel of Fortune to win a price.
[http://localhost:8080/wheel-of-fortune](http://localhost:8080/wheel-of-fortune)
## Go service
Service interface defintion
```go reference title="server/services/wof/service.go"
https://github.com/foomo/gotsrpc-playground/blob/main/server/services/wof/service.go
```
Service implementation
```go reference title="server/services/helloworld/service.go"
https://github.com/foomo/gotsrpc-playground/blob/main/server/server/wof.go
```
## Next.js TypeScript client
```typescript reference title="client/pages/wheel-of-fortune.tsx"
https://github.com/foomo/gotsrpc-playground/blob/main/client/pages/wheel-of-fortune.tsx
```

View File

@ -0,0 +1,18 @@
# Todos
## Go Service
Service interface defintion
```go reference title="server/services/wof/service.go" lines
https://github.com/foomo/gotsrpc-playground/blob/main/server/services/todos/service.go
```
Service implementation
```go reference title="server/services/helloworld/service.go"
https://github.com/foomo/gotsrpc-playground/blob/main/server/server/todos.go
```
## Next.js TypeScript client

View File

@ -0,0 +1,62 @@
# Playground
The gotsrpc playground is designed to:
- provide examples for this documentation
- make it easy to play with gotsrpc on your local machine
It is **NOT** an example project to build an actual production service, because:
- it has a purely educational layout
- all services are exposed from one go program
- all service implementations are naive demo code with focus on documentation
- all service implementations are in one package
## Installing and running the playground
Prerequisites
- Go
- Node.js
Clone repo
```shell
git clone git@github.com:foomo/gotsrpc-playground.git ~/go/src/github.com/foomo/gotsrpc-playground
```
Run playground
```shell
cd ~/go/src/github.com/foomo/gotsrpc-playground
make run
```
Open the playground http://127.0.0.1:8080
## Project layout
Note : this is not a recommendation for a general project layout - it is purely educational.
| Location | Description |
| -------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `server` | server go code |
| `server/services` | service interfaces, one service interface per package helloworld, todos, ... |
| `server/server` | One package to implement all service interfaces with one file per service package - in a real world scenario, that typically is one package per service interface |
| `server/main.go` | Go program, that exposes all service implementations and reverse proxies the Next.js frontend which is running on http://127.0.0.1:3000 |
| `client` | Next.js TypeScript client created with `npx create-next-app@latest --typescript` |
| [`client/services/transport.ts`](https://github.com/foomo/gotsrpc-playground/blob/main/client/services/transport.ts) | An example transport implemenation |
| `client/services/generated` | Target for generated TypeScript clients and value objects as defined in `gotsrpc.yaml` |
ie relevant files per example:
| File | Description |
| -------------------------------------- | ---------------------------- |
| `server/services/<example>/service.go` | service interface definition |
| `server/server/<example>.go` | service implementation |
| `client/pages/<example>.tsx` | Next.js example page |
| `client/styles/<Example>.module.css` | CSS |

View File

@ -0,0 +1,31 @@
# gotsrpc.yaml
Typically there will be one central `gotsrpc.yaml` file per project.
## Purpose
### Go code generation rules
- service proxy generation
- client generation
### TypeScript code generation rules
- file names for clients in [Targets](#targets)
- file names for value object code generation [Mappings](#mappings)
## gotsrpc.yaml file sections
### Targets
Think of targets as build targets. A target is defined for all services in a package
```yml reference title="playground gotspc.yaml"
https://github.com/foomo/gotsrpc-playground/blob/main/gotsrpc.yaml#L1-L16
```
### Mappings
```yml reference title="playground gotspc.yaml"
https://github.com/foomo/gotsrpc-playground/blob/main/gotsrpc.yaml#L43-L46
```

View File

@ -0,0 +1,46 @@
# gotsrpc
https://github.com/foomo/gotsrpc
Generated Go RPC service proxies for generated Go and TypeScript clients.
**`gotsrpc` ensures type safety and seamless integration of Go RPC services and TypeScript clients**
Everything starts with a Go interface definition. The gotsrpc command line tool can the be used to generate a Go service proxy and TypeScript and Go clients. The next step is to implement the interface in Go and expose it to http requests with the generated service proxies.
## Use cases
Who can do what with gotsrpc?
### Go developers
- expose Go interfaces as http RPC services
- consume Go interfaces with generated clients
### TypeScript developers
- consume APIs written in Go through an idiomatic TypeScript interface
## Design and architectural goals
- code first approach
- generated integration of TypeScript or Go clients and Go servers
- high productivity
- low latency between clients and servers
- good integration with browser dev tools (gotsrpc calls read well in the network tab)
- light weight clients
- idiomatic Go and TypeScript
- type safety between clients and servers
## Architectural notes
### Why not REST?
Fast and light weight frontends are hard to build on REST interfaces in an efficient manner. Also see the motivations behind GraphQL.
### Why not GraphQL?
GraphQL is great, when backend developers and thus custom backends are not available to the frontend team. In our experience writing Go services that provide dedicated gotsrpc interfaces works great - especially, if your are striving for high performance and low latencies.
This only works for teams in which frontend and backend developers work closely together.

View File

@ -0,0 +1,56 @@
# Protocol
A gotsrpc method call is a **http POST** of an **array of arguments** to `http(s)://host/path/to/service/endpoint/<Method>`, that will return an **array of return values**. By default JSON is used for serialization.
Gotsrpc calls are not RESTful, but access to the underlying http requests and responses is possible. This is usually used for header access.
## HTTP status codes
The response status code is
- 200 for all responses (including the ones with business logic errors)
- 500 when the go code, that implements the service interface panics
## Encoding / Marshalling
`gotsrpc` supports
- [JSON](https://www.json.org/) (default)
- [MessagePack](https://msgpack.org/)
- [gob](https://pkg.go.dev/encoding/gob)
:::note
**gotsrpc service proxies are not using streaming encoders or decoders**:
- incoming data will be read completely from the request body
- decoding / unmarshalling is not streaming (for all encodings)
- return values will be encoded / marshalled in the same manner
- the response is streamed
Thus you should **use paging, when transferring a lot of data**.
:::
## Curl example call to a running playground server
A curl call tells more than a thousand words:
```shell
curl -v --data-raw '["Visitor"]' http://localhost:8080/services/helloworld/Hello
# > POST /services/helloworld/Hello HTTP/1.1
# > Host: localhost:8080
# >
# < HTTP/1.1 200 OK
# < Content-Type: application/json; charset=utf-8
# <
# ["Hello Visitor"]
```
When debugging and inspecting from the command line the `fx` command is very helpful https://github.com/antonmedv/fx
```shell
curl -v --data-raw '["Visitor"]' http://localhost:8080/services/helloworld/Hello | fx
# starts fx which will read the server response from stdin
# and provide a nice interactive json viewer
```

View File

@ -1,2 +0,0 @@
# Site reliability

View File

@ -15,10 +15,10 @@
"typecheck": "tsc"
},
"dependencies": {
"@docusaurus/core": "2.3.1",
"@docusaurus/preset-classic": "^2.3.1",
"@docusaurus/theme-live-codeblock": "^2.3.1",
"@docusaurus/theme-search-algolia": "^2.3.1",
"@docusaurus/core": "^2.4.0",
"@docusaurus/preset-classic": "^2.4.0",
"@docusaurus/theme-live-codeblock": "^2.4.0",
"@docusaurus/theme-search-algolia": "^2.4.0",
"@mdx-js/react": "^1.6.21",
"@saucelabs/theme-github-codeblock": "0.1.1",
"@svgr/webpack": "^5.5.0",
@ -32,7 +32,7 @@
"url-loader": "^4.1.1"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "^2.3.1",
"@docusaurus/module-type-aliases": "^2.4.0",
"@tsconfig/docusaurus": "^1.0.4",
"typescript": "^4.9.5"
},

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,13 @@
{
"devDependencies": {
"@docusaurus/module-type-aliases": "^2.3.1",
"@docusaurus/module-type-aliases": "^2.4.0",
"@tsconfig/docusaurus": "^1.0.6",
"typescript": "^4.9.5"
},
"dependencies": {
"@docusaurus/core": "^2.4.0",
"@docusaurus/preset-classic": "^2.4.0",
"@docusaurus/theme-live-codeblock": "^2.4.0",
"@docusaurus/theme-search-algolia": "^2.4.0"
}
}

7150
yarn.lock

File diff suppressed because it is too large Load Diff