Skip to content

Commit 2a0758a

Browse files
authored
Merge pull request #64 from flashcatcloud/docs/go-sdk-intro-and-navbar-i18n
docs: add Go SDK guide and make API Reference navbar language-aware
2 parents 4c42a25 + 61bd9cd commit 2a0758a

6 files changed

Lines changed: 365 additions & 2 deletions

File tree

.mintignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# Cursor IDE configuration and skills
22
.cursor/
33

4+
# Tooling staging/output dirs (doc-review / api-review skills) — never docs content
5+
.doc-review-staging/
6+
.doc-review/
7+
.api-review/
8+
49
# Project documentation (non-mdx files)
510
AGENTS.md
611
README.md

docs.json

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,20 @@
2222
"languages": [
2323
{
2424
"language": "zh",
25+
"navbar": {
26+
"links": [
27+
{
28+
"label": "API 参考",
29+
"icon": "code",
30+
"href": "/zh/openapi/introduction"
31+
}
32+
],
33+
"primary": {
34+
"type": "button",
35+
"label": "控制台",
36+
"href": "https://console.flashcat.cloud"
37+
}
38+
},
2539
"tabs": [
2640
{
2741
"tab": "首页",
@@ -514,7 +528,8 @@
514528
"pages": [
515529
"zh/openapi/introduction",
516530
"zh/openapi/api-catalog",
517-
"zh/openapi/pagination"
531+
"zh/openapi/pagination",
532+
"zh/openapi/go-sdk"
518533
]
519534
},
520535
{
@@ -1059,6 +1074,20 @@
10591074
},
10601075
{
10611076
"language": "en",
1077+
"navbar": {
1078+
"links": [
1079+
{
1080+
"label": "API Reference",
1081+
"icon": "code",
1082+
"href": "/en/openapi/introduction"
1083+
}
1084+
],
1085+
"primary": {
1086+
"type": "button",
1087+
"label": "Console",
1088+
"href": "https://console.flashcat.cloud"
1089+
}
1090+
},
10621091
"tabs": [
10631092
{
10641093
"tab": "Home",
@@ -1551,7 +1580,8 @@
15511580
"pages": [
15521581
"en/openapi/introduction",
15531582
"en/openapi/api-catalog",
1554-
"en/openapi/pagination"
1583+
"en/openapi/pagination",
1584+
"en/openapi/go-sdk"
15551585
]
15561586
},
15571587
{

en/openapi/go-sdk.mdx

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
---
2+
title: "Go SDK"
3+
description: "go-flashduty — the official Go client for the Flashduty Open API"
4+
keywords: ["Go SDK", "go-flashduty", "Golang", "Open API", "client", "SDK"]
5+
---
6+
7+
[`go-flashduty`](https://github.com/flashcatcloud/go-flashduty) is the official Go client for the Flashduty Open API — a thin, strongly-typed SDK. It is generated from the same OpenAPI specification this documentation is built on, covers every Open API endpoint, and is validated by unit tests and end-to-end against the live API.
8+
9+
If your service is written in Go, use the SDK to call Flashduty rather than hand-writing HTTP requests — you get typed request parameters, response structs, and error codes out of the box, with no manual JSON assembly or response parsing.
10+
11+
<Tip>
12+
The SDK shares the same endpoint semantics as the Open API. Every request/response structure documented here maps to a corresponding type in the SDK. Authentication uses the same [APP Key](/en/openapi/introduction#authentication).
13+
</Tip>
14+
15+
## Install
16+
17+
Requires Go 1.24 or later.
18+
19+
```bash
20+
go get github.com/flashcatcloud/go-flashduty
21+
```
22+
23+
## Quick start
24+
25+
Create a client with your APP Key and call endpoints grouped by service (`client.Incidents`, `client.Alerts`, …). Each method maps to exactly one HTTP call and returns `(*T, *Response, error)`:
26+
27+
```go
28+
package main
29+
30+
import (
31+
"context"
32+
"fmt"
33+
"log"
34+
35+
flashduty "github.com/flashcatcloud/go-flashduty"
36+
)
37+
38+
func main() {
39+
client, err := flashduty.NewClient("YOUR_APP_KEY")
40+
if err != nil {
41+
log.Fatal(err)
42+
}
43+
44+
list, resp, err := client.Incidents.List(context.Background(), &flashduty.ListIncidentsRequest{
45+
Progress: "Triggered",
46+
ListOptions: flashduty.ListOptions{Limit: 20},
47+
})
48+
if err != nil {
49+
log.Fatal(err)
50+
}
51+
52+
fmt.Printf("request_id=%s total=%d has_next=%t\n", resp.RequestID, resp.Total, resp.HasNextPage)
53+
for _, inc := range list.Items {
54+
fmt.Printf("[%s] %s\n", inc.IncidentSeverity, inc.Title)
55+
}
56+
}
57+
```
58+
59+
## Design
60+
61+
<CardGroup cols={2}>
62+
<Card title="Thin and typed" icon="feather">
63+
Every method maps to exactly one HTTP call and returns `(*T, *Response, error)`. No hidden cross-endpoint enrichment.
64+
</Card>
65+
<Card title="Service-grouped" icon="layer-group">
66+
Endpoints are organized into services on the client (`client.Incidents`, `client.Alerts`, …), generated from the OpenAPI specification.
67+
</Card>
68+
<Card title="Composable transport" icon="puzzle-piece">
69+
Cross-cutting concerns (retry, caching, tracing, rate-limit handling) compose as `http.RoundTripper` middleware via `WithTransport`.
70+
</Card>
71+
<Card title="Human-readable timestamps" icon="clock">
72+
Response time fields are typed `Timestamp` / `TimestampMilli`, rendering as RFC3339 in JSON, logs, and LLM-facing output — while the raw epoch is one call away.
73+
</Card>
74+
</CardGroup>
75+
76+
## Options
77+
78+
`NewClient` accepts a set of options:
79+
80+
```go
81+
client, err := flashduty.NewClient("YOUR_APP_KEY",
82+
flashduty.WithBaseURL("https://api.flashcat.cloud"),
83+
flashduty.WithTimeout(10*time.Second),
84+
flashduty.WithUserAgent("my-app/1.0"),
85+
flashduty.WithHTTPClient(customHTTPClient),
86+
flashduty.WithTransport(customRoundTripper),
87+
flashduty.WithLogger(myLogger),
88+
flashduty.WithRequestHeaders(staticHeaders),
89+
flashduty.WithRequestHook(func(req *http.Request) { /* e.g. inject traceparent */ }),
90+
)
91+
```
92+
93+
## Errors and rate limits
94+
95+
The SDK returns typed errors you can unwrap with `errors.As`, plus convenience predicates that see through wrapped errors:
96+
97+
```go
98+
_, _, err := client.Incidents.Info(ctx, &flashduty.IncidentInfoRequest{IncidentID: "does-not-exist"})
99+
100+
var apiErr *flashduty.ErrorResponse
101+
if errors.As(err, &apiErr) {
102+
fmt.Println(apiErr.Code, apiErr.RequestID)
103+
}
104+
105+
var rl *flashduty.RateLimitError
106+
if errors.As(err, &rl) {
107+
time.Sleep(rl.RetryAfter)
108+
}
109+
110+
// Convenience predicates
111+
if flashduty.IsNotFound(err) { /* ... */ }
112+
if flashduty.IsRateLimited(err) { /* ... */ }
113+
switch flashduty.ErrorCodeOf(err) {
114+
case flashduty.ErrorCodeAccessDenied, flashduty.ErrorCodeUnauthorized:
115+
// handle auth failures
116+
}
117+
```
118+
119+
Error codes map one-to-one to the [Error Code List](/en/openapi/introduction#error-code-list).
120+
121+
## Timestamps
122+
123+
Time fields on responses are typed `Timestamp` (Unix seconds) or `TimestampMilli` (milliseconds). They marshal to an RFC3339 string in the local timezone and unmarshal from either a numeric epoch or an RFC3339 string, so a value round-trips cleanly. The zero value stays the numeric `0` sentinel (never a 1970 date) and is dropped by `omitempty`.
124+
125+
```go
126+
inc := list.Items[0]
127+
fmt.Println(inc.StartTime) // 2026-05-30T14:37:11+08:00 (String / fmt / TOON)
128+
b, _ := json.Marshal(inc.StartTime) // "2026-05-30T14:37:11+08:00"
129+
epoch := inc.StartTime.Unix() // 1779514631 (raw wire value)
130+
t := inc.StartTime.Time() // time.Time
131+
```
132+
133+
<Note>
134+
Request time fields stay plain `int64` — the API expects a numeric epoch on the wire. Most endpoints take **seconds**, but RUM and webhook-history endpoints take **milliseconds**.
135+
</Note>
136+
137+
## Retries
138+
139+
Automatic retries are **not** built into the core. Compose them at the transport layer with the optional `retry` subpackage — a safe-by-default retrying `http.RoundTripper` (retries 429 and 5xx, honors `Retry-After`, deterministic exponential backoff, and only replays requests whose body is replayable, which all SDK requests are):
140+
141+
```go
142+
import "github.com/flashcatcloud/go-flashduty/retry"
143+
144+
client, err := flashduty.NewClient("YOUR_APP_KEY",
145+
flashduty.WithTransport(retry.New(
146+
retry.WithMaxRetries(3),
147+
)),
148+
)
149+
```
150+
151+
## Resources
152+
153+
<CardGroup cols={2}>
154+
<Card title="GitHub repository" icon="github" href="https://github.com/flashcatcloud/go-flashduty">
155+
Source, full README, and issues. Licensed under Apache-2.0.
156+
</Card>
157+
<Card title="API Catalog" icon="list" href="/en/openapi/api-catalog">
158+
Browse every endpoint — each maps to a typed method in the SDK.
159+
</Card>
160+
</CardGroup>

en/openapi/introduction.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ curl -X POST 'https://api.flashcat.cloud/your/api/path?app_key=YOUR_APP_KEY' \
7070
-d '{"param": "value"}'
7171
```
7272

73+
<Note>
74+
Using Go? Use the official [Go SDK](/en/openapi/go-sdk) to call Flashduty — you get typed request parameters, response structs, and error codes out of the box, with no hand-written HTTP.
75+
</Note>
76+
7377
---
7478

7579
## Response Structure

0 commit comments

Comments
 (0)