下面讓我來們建立一個很是精簡的 Go kit 服務
業務邏輯邏輯
服務(Service)是從業務邏輯開始的,在 Go kit 中,咱們將服務以 interface 做爲模型
1
2
3
4
5
|
// StringService provides operations on strings.
type
StringService
interface
{
Uppercase
(
string
)
(
string
,
error
)
Count
(
string
)
int
}
|
這個 interface 須要有一個「實現」
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
type
stringService
struct
{
}
func
(
stringService
)
Uppercase
(
s
string
)
(
string
,
error
)
{
if
s
==
""
{
return
""
,
ErrEmpty
}
return
strings
.
ToUpper
(
s
)
,
nil
}
func
(
stringService
)
Count
(
s
string
)
int
{
return
len
(
s
)
}
// ErrEmpty is returned when input string is empty
var
ErrEmpty
=
errors
.
New
(
"Empty string"
)
|
請求和響應
在 Go kit 中,主要的消息模式是 RPC。所以,接口( interface )的每個方法都會被模型化爲遠程過程調用(RPC)。對於每個方法,咱們都定義了請求和響應的結構體,捕獲輸入、輸出各自的全部參數。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
type
uppercaseRequest
struct
{
S
string
`
json
:
"s"
`
}
type
uppercaseResponse
struct
{
V
string
`
json
:
"v"
`
Err
string
`
json
:
"err,omitempty"
`
// errors don't define JSON marshaling
}
type
countRequest
struct
{
S
string
`
json
:
"s"
`
}
type
countResponse
struct
{
V
int
`
json
:
"v"
`
}
|
端點 (endpoint)
Go kit 經過 endpoint 提供了很是豐富的功能。
一個端點表明一個RPC,也就是咱們服務接口中的一個函數。咱們將編寫簡單的適配器,將咱們的服務的每個方法轉換成端點。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import
(
"golang.org/x/net/context"
"github.com/go-kit/kit/endpoint"
)
func
makeUppercaseEndpoint
(
svc
StringService
)
endpoint
.
Endpoint
{
return
func
(
ctx
context
.
Context
,
request
interface
{
}
)
(
interface
{
}
,
error
)
{
req
:
=
request
.
(
uppercaseRequest
)
v
,
err
:
=
svc
.
Uppercase
(
req
.
S
)
if
err
!=
nil
{
return
uppercaseResponse
{
v
,
err
.
Error
(
)
}
,
nil
}
return
uppercaseResponse
{
v
,
""
}
,
nil
}
}
func
makeCountEndpoint
(
svc
StringService
)
endpoint
.
Endpoint
{
return
func
(
ctx
context
.
Context
,
request
interface
{
}
)
(
interface
{
}
,
error
)
{
req
:
=
request
.
(
countRequest
)
v
:
=
svc
.
Count
(
req
.
S
)
return
countResponse
{
v
}
,
nil
}
}
|
傳輸(Transports)
如今咱們須要將服務暴露給外界,這樣它們才能被調用。對於服務如何與外界交互,你的組織可能已經有了定論。可能你會使用 Thrift、基於 HTTP 的自定義 JSON。Go kit支持多種開箱即用的 傳輸 方式。(Adding support for new ones is easy—just 對新方式的支持是很是簡單的。參見 這裏
針對咱們如今的這個微型的服務例子,咱們使用基於 HTTP 的 JSON。Go kit 中提供了一個輔助結構體,在 transport/http 中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
import
(
"encoding/json"
"log"
"net/http"
"golang.org/x/net/context"
httptransport
"github.com/go-kit/kit/transport/http"
)
func
main
(
)
{
ctx
:
=
context
.
Background
(
)
svc
:
=
stringService
{
}
uppercaseHandler
:
=
httptransport
.
NewServer
(
ctx
,
makeUppercaseEndpoint
(
svc
)
,
decodeUppercaseRequest
,
encodeResponse
,
)
countHandler
:
=
httptransport
.
NewServer
(
ctx
,
makeCountEndpoint
(
svc
)
,
decodeCountRequest
,
encodeResponse
,
)
http
.
Handle
(
"/uppercase"
,
uppercaseHandler
)
http
.
Handle
(
"/count"
,
countHandler
)
log
.
Fatal
(
http
.
ListenAndServe
(
":8080"
,
nil
)
)
}
func
decodeUppercaseRequest
(
_
context
.
Context
,
r *
http
.
Request
)
(
interface
{
}
,
error
)
{
var
request
uppercaseRequest
if
err
:
=
json
.
NewDecoder
(
r
.
Body
)
.
Decode
(
&
amp
;
request
)
;
err
!=
nil
{
return
nil
,
err
}
return
request
,
nil
}
func
decodeCountRequest
(
_
context
.
Context
,
r *
http
.
Request
)
(
interface
{
}
,
error
)
{
var
request
countRequest
if
err
:
=
json
.
NewDecoder
(
r
.
Body
)
.
Decode
(
&
amp
;
request
)
;
err
!=
nil
{
return
nil
,
err
}
return
request
,
nil
}
func
encodeResponse
(
_
context
.
Context
,
w
http
.
ResponseWriter
,
response
interface
{
}
)
error
{
return
json
.
NewEncoder
(
w
)
.
Encode
(
response
)
}
|