-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathclient.go.tmpl
128 lines (109 loc) · 3.93 KB
/
client.go.tmpl
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
{{define "client"}}
{{- $typeMap := .TypeMap -}}
{{- $opts := .Opts -}}
{{- if .Services}}
{{- range .Services}}
class {{.Name}}Impl implements {{.Name}} {
{{.Name}}Impl(String hostname, [WebrpcHttpClient? httpClient])
: _baseUrl = '$hostname/rpc/{{.Name}}/',
_httpClient = httpClient ?? _MainWebrpcHttpClient();
final String _baseUrl;
final WebrpcHttpClient _httpClient;
{{- range $_, $method := .Methods}}
@override
Future<{{template "methodOutputs" dict "Method" . "TypeMap" $typeMap}}> {{firstLetterToLower .Name}}({{template "methodInputs" dict "Method" . "TypeMap" $typeMap}}) async {
{{- if gt (len .Inputs) 0}}
final String body = jsonEncode(toJsonObject({
{{if true}}{{end}}
{{- range $i, $input := .Inputs -}}
{{indent 4 ""}}'{{$input.Name}}': {{$input.Name}},
{{end -}}
}));
{{else}}
final String? body = null;
{{end -}}
WebrpcHttpRequest request = WebrpcHttpRequest(
uri: _makeUri('{{.Name}}'),
headers: _makeHeaders(),
body: body,
);
final WebrpcHttpResponse response = await _httpClient.post(request);
{{if eq (len $method.Outputs) 0 -}}
await _handleResponse(response);
{{- else -}}
await _handleResponse(response);
final Map<String, dynamic> json = jsonDecode(response.body);
return (
{{if true}}{{end}}
{{- range $i, $output := .Outputs -}}
{{if true}} {{end}}{{$output.Name}}: _{{firstLetterToLower $method.Name}}{{firstLetterToUpper .Name}}(json['{{$output.Name}}']),
{{end -}}
);
{{- end}}
}
{{- range $i, $output := .Outputs}}
{{if true}}{{end}}
static {{template "type" dict "Type" $output.Type "TypeMap" $typeMap}}{{if .Optional}}?{{end}} _{{firstLetterToLower $method.Name}}{{firstLetterToUpper .Name}}(dynamic v0) {
{{- template "fromJson" dict "Type" $output.Type "TypeMap" $typeMap "Optional" .Optional}}
return r0;
}
{{- end}}
{{- end}}
Uri _makeUri(String name) {
return Uri.parse(_baseUrl + name);
}
static Map<String, Object> _makeHeaders() {
return {
'Content-Type': 'application/json',
'Accept': 'application/json',
};
}
Future<void> _handleResponse(WebrpcHttpResponse response) async {
if (response.statusCode >= 400) {
try {
final Map<String, dynamic> json = jsonDecode(response.body);
final int webrpcErrorCode = json['code'];
if (response.statusCode >= 500) {
throw WebrpcException.fromCode(webrpcErrorCode);
} else {
throw WebrpcError.fromCode(webrpcErrorCode);
}
} on ArgumentError catch (_) {
// https://github.com/webrpc/webrpc/blob/master/gen/errors.go
throw WebrpcException.fromCode(-5);
}
}
}
}
{{- end -}}
{{- end}}
class _MainWebrpcHttpClient implements WebrpcHttpClient {
@override
Future<WebrpcHttpResponse> post(WebrpcHttpRequest request) async {
final http.Response response = await http.post(
request.uri,
body: request.body == null ? null : utf8.encode(request.body!),
headers: request.headers.map((key, value) => MapEntry(key, value.toString())),
);
return WebrpcHttpResponse(statusCode: response.statusCode, body: response.body);
}
}
abstract interface class WebrpcHttpClient {
Future<WebrpcHttpResponse> post(WebrpcHttpRequest request);
}
class WebrpcHttpRequest {
WebrpcHttpRequest({
required this.uri,
required this.headers,
required this.body,
});
final Uri uri;
final Map<String, Object> headers;
final String? body;
}
class WebrpcHttpResponse {
WebrpcHttpResponse({required this.statusCode, required this.body});
final int statusCode;
final String body;
}
{{- end -}}