Skip to content

Commit acaebe1

Browse files
committed
mo
1 parent d1a2277 commit acaebe1

14 files changed

Lines changed: 1103 additions & 0 deletions

docs/basic.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Implement Basic Auth
2+
3+
- Add basic auth middleware to `dics/container.go`
4+
5+
```go
6+
{
7+
Name: "bima:middleware:basic-auth",
8+
Scope: bima.Application,
9+
Build: (*middlewares.BasicAuth)(nil),
10+
Params: dingo.Params{
11+
"Validator": func(username, password string) bool {
12+
return true
13+
},
14+
},
15+
},
16+
```
17+
18+
You need to implement `Validator` with your own logic
19+
20+
- Add to `configs/middlewares.yaml`
21+
22+
```yaml
23+
middlewares:
24+
- basic-auth
25+
```
26+

docs/convert_middleware.md

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# Convert Middleware
2+
3+
For this example, i use `https://github.com/didip/tollbooth`
4+
5+
- Create `rate_limit.go` inside `middlewares` folder (you can create when folder not exists)
6+
7+
- Copas placeholder code
8+
9+
```go
10+
package middlewares
11+
12+
import (
13+
"net/http"
14+
)
15+
16+
type RateLimit struct {
17+
}
18+
19+
func (r *RateLimit) Attach(request *http.Request, response http.ResponseWriter) bool {
20+
}
21+
22+
func (r *RateLimit) Priority() int {
23+
return 0
24+
}
25+
26+
```
27+
28+
- Look up to the handler function
29+
30+
From readme, we know when we want to use `https://github.com/didip/tollbooth`, we just add one line like below
31+
32+
```go
33+
tollbooth.LimitFuncHandler(tollbooth.NewLimiter(1, nil), HelloHandler)
34+
```
35+
36+
See inside `tollbooth.LimitFuncHandler()` and here the code
37+
38+
```go
39+
middle := func(w http.ResponseWriter, r *http.Request) {
40+
httpError := LimitByRequest(lmt, w, r)
41+
if httpError != nil {
42+
lmt.ExecOnLimitReached(w, r)
43+
if lmt.GetOverrideDefaultResponseWriter() {
44+
return
45+
}
46+
w.Header().Add("Content-Type", lmt.GetMessageContentType())
47+
w.WriteHeader(httpError.StatusCode)
48+
w.Write([]byte(httpError.Message))
49+
return
50+
}
51+
52+
// There's no rate-limit error, serve the next handler.
53+
next.ServeHTTP(w, r)
54+
}
55+
56+
return http.HandlerFunc(middle)
57+
```
58+
59+
- Find `func(w http.ResponseWriter, r *http.Request)` function and copas the body to your middleware, like below (i change variable names)
60+
61+
```go
62+
limiter := tollbooth.NewLimiter(1, nil)
63+
httpError := tollbooth.LimitByRequest(limiter, response, request)
64+
if httpError != nil {
65+
limiter.ExecOnLimitReached(response, request)
66+
if limiter.GetOverrideDefaultResponseWriter() {
67+
return true
68+
}
69+
70+
response.Header().Add("Content-Type", limiter.GetMessageContentType())
71+
response.WriteHeader(httpError.StatusCode)
72+
response.Write([]byte(httpError.Message))
73+
74+
return true
75+
}
76+
77+
return false
78+
```
79+
80+
Here full code
81+
82+
```go
83+
package middlewares
84+
85+
import (
86+
"net/http"
87+
88+
"github.com/didip/tollbooth/v6"
89+
)
90+
91+
type RateLimit struct {
92+
}
93+
94+
func (r *RateLimit) Attach(request *http.Request, response http.ResponseWriter) bool {
95+
limiter := tollbooth.NewLimiter(1, nil)
96+
httpError := tollbooth.LimitByRequest(limiter, response, request)
97+
if httpError != nil {
98+
limiter.ExecOnLimitReached(response, request)
99+
if limiter.GetOverrideDefaultResponseWriter() {
100+
return true
101+
}
102+
103+
response.Header().Add("Content-Type", limiter.GetMessageContentType())
104+
response.WriteHeader(httpError.StatusCode)
105+
response.Write([]byte(httpError.Message))
106+
107+
return true
108+
}
109+
110+
return false
111+
}
112+
113+
func (r *RateLimit) Priority() int {
114+
return 0
115+
}
116+
117+
```
118+
119+
- Add definition to `dics/container.go`
120+
121+
```go
122+
{
123+
Name: "bima:middleware:rate-limiter",
124+
Scope: bima.Application,
125+
Build: (*middlewares.RateLimit)(nil),
126+
},
127+
```
128+
129+
- Add to `configs/middlewares.yaml`
130+
131+
```yaml
132+
middlewares:
133+
- rate-limiter
134+
```
135+
136+
- Add `max` value optional
137+
138+
```go
139+
type RateLimit struct {
140+
Max float64
141+
}
142+
143+
func (r *RateLimit) Attach(request *http.Request, response http.ResponseWriter) bool {
144+
limiter := tollbooth.NewLimiter(r.Max, nil)
145+
httpError := tollbooth.LimitByRequest(limiter, response, request)
146+
if httpError != nil {
147+
limiter.ExecOnLimitReached(response, request)
148+
if limiter.GetOverrideDefaultResponseWriter() {
149+
return true
150+
}
151+
152+
response.Header().Add("Content-Type", limiter.GetMessageContentType())
153+
response.WriteHeader(httpError.StatusCode)
154+
response.Write([]byte(httpError.Message))
155+
156+
return true
157+
}
158+
159+
return false
160+
}
161+
```
162+
163+
- Change definition
164+
165+
```go
166+
{
167+
Name: "bima:middleware:rate-limiter",
168+
Scope: bima.Application,
169+
Build: (*middlewares.RateLimit)(nil),
170+
Params: dingo.Params{
171+
"Max": float64(1),
172+
},
173+
},
174+
```
175+
176+
![Rate limiter](../assets/rate-limit-header.png)

docs/cors.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Enable CORS
2+
3+
- Add CORS middleware to `dics/container.go`
4+
5+
```go
6+
{
7+
Name: "bima:middleware:cors",
8+
Scope: bima.Application,
9+
Build: (*middlewares.Cors)(nil),
10+
Params: dingo.Params{
11+
"Options": cors.Options{},
12+
},
13+
},
14+
```
15+
16+
You can refer to [cors](github.com/rs/cors) for more options
17+
18+
- Add to `configs/middlewares.yaml`
19+
20+
```yaml
21+
middlewares:
22+
- cors
23+
```

docs/custom_action.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Add Custom Action
2+
3+
This tutorial will explain how to add custom action (service) to your gRPC (proto)
4+
5+
- Add new service
6+
7+
```proto
8+
rpc Done (Todo) returns (TodoResponse) {
9+
option (google.api.http) = {
10+
post: "/api/v1/todos/{id}/done"
11+
};
12+
}
13+
```
14+
15+
We add new `Done` service with `/api/v1/todos/{id}/done` as path and use `POST` HTTP method
16+
17+
- Update generated code using `bima generate` and refresh your browser
18+
19+
![Custom Action](../assets/custom-action.png)
20+
21+
![Custom Action Unimplemented](../assets/custom-action-unimplemented.png)
22+
23+
- Implement `Done` service
24+
25+
```go
26+
func (m *Module) Done(ctx context.Context, r *grpcs.Todo) (*grpcs.TodoResponse, error) {
27+
ctx = context.WithValue(ctx, "scope", "todo")
28+
v := m.Model
29+
copier.Copy(v, r)
30+
if err := m.Handler.Bind(v, r.Id); err != nil {
31+
loggers.Logger.Error(ctx, err.Error())
32+
33+
return nil, status.Error(codes.NotFound, fmt.Sprintf("Data with ID '%s' not found.", r.Id))
34+
}
35+
36+
v.Done = true
37+
if err := m.Handler.Update(v, v.Id); err != nil {
38+
loggers.Logger.Error(ctx, err.Error())
39+
40+
return nil, status.Error(codes.Internal, "Internal server error")
41+
}
42+
43+
r.Done = v.Done
44+
m.Cache.Invalidate(r.Id)
45+
46+
return &grpcs.TodoResponse{
47+
Todo: r,
48+
}, nil
49+
}
50+
51+
```
52+
53+
- Rerun and recall your new action
54+
55+
56+
![Custom Action Unimplemented](../assets/custom-action-implemented.png)

docs/debug.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Debugging using Remote Debug
2+
3+
- Run application using debug mode `bima run debug`
4+
5+
- Copy PID
6+
7+
- Run debugger `bima debug <pid>`
8+
9+
- Bima Framework reserved `16517` port number as debug port, you can use it for any IDE that support remote debug
10+
11+
- For VS Code user, copy `launch.json` below
12+
13+
```json
14+
{
15+
"version": "0.2.0",
16+
"configurations": [
17+
{
18+
"name": "Debug",
19+
"type": "go",
20+
"request": "attach",
21+
"mode": "remote",
22+
"port": 16517,
23+
"remotePath": "${workspaceFolder}",
24+
"host": "127.0.0.1",
25+
"cwd": "${workspaceFolder}"
26+
}
27+
]
28+
}
29+
30+
```
31+
32+
- Just use Debug Panel as usual

docs/driver.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Create Own Database Driver
2+
3+
- We use `sqlite` for this example `https://gorm.io/docs/connecting_to_the_database.html#SQLite`
4+
5+
- Create `sqlite.go` and here the code
6+
7+
```go
8+
package drivers
9+
10+
import (
11+
"gorm.io/driver/sqlite"
12+
"gorm.io/gorm"
13+
)
14+
15+
type Sqlite string
16+
17+
func (s Sqlite) Name() string {
18+
return string(s)
19+
}
20+
21+
func (_ Sqlite) Connect(_ string, _ int, _ string, _ string, dbname string, _ bool) *gorm.DB {
22+
db, err := gorm.Open(sqlite.Open(dbname), &gorm.Config{})
23+
if err != nil {
24+
panic(err)
25+
}
26+
27+
return db
28+
}
29+
30+
```
31+
32+
- Add definition to `dics/container.go`
33+
34+
```go
35+
{
36+
Name: "bima:driver:sqlite",
37+
Scope: bima.Application,
38+
Build: func() (*drivers.Sqlite, error) {
39+
return Sqlite("sqlite")
40+
},
41+
},
42+
```
43+
44+
- Add to `configs/drivers.yaml`
45+
46+
```yaml
47+
drivers:
48+
- sqlite
49+
```

0 commit comments

Comments
 (0)