Skip to content

Commit 3148c5a

Browse files
authored
Merge pull request #192 from ShiqiuC/add-java-okhttp-codegen
feat: add codegen for Java(okhttp)
2 parents b8cb684 + 12177fc commit 3148c5a

File tree

5 files changed

+1227
-0
lines changed

5 files changed

+1227
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ API Dash currently supports API integration code generation for the following la
135135
| Python | `http.client` |
136136
| Python | `requests` |
137137
| Kotlin | `okhttp3` |
138+
| Java | `okhttp3` |
138139

139140
We welcome contributions to support other programming languages/libraries/frameworks. Please check out more details [here](https://github.com/foss42/apidash/discussions/80).
140141

lib/codegen/codegen.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import 'js/fetch.dart';
1515
import 'others/har.dart';
1616
import 'others/curl.dart';
1717
import 'julia/http.dart';
18+
import 'java/okhttp.dart';
1819

1920
class Codegen {
2021
String? getCode(
@@ -52,6 +53,8 @@ class Codegen {
5253
return FetchCodeGen(isNodeJs: true).getCode(rM);
5354
case CodegenLanguage.kotlinOkHttp:
5455
return KotlinOkHttpCodeGen().getCode(rM);
56+
case CodegenLanguage.javaOkHttp:
57+
return JavaOkHttpCodeGen().getCode(rM);
5558
case CodegenLanguage.pythonHttpClient:
5659
return PythonHttpClientCodeGen()
5760
.getCode(rM, boundary: boundary ?? getNewUuid());

lib/codegen/java/okhttp.dart

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
import 'dart:convert';
2+
import 'package:jinja/jinja.dart' as jj;
3+
import 'package:apidash/utils/utils.dart'
4+
show getValidRequestUri, stripUriParams;
5+
import '../../models/request_model.dart';
6+
import 'package:apidash/consts.dart';
7+
8+
class JavaOkHttpCodeGen {
9+
final String kTemplateStart = """
10+
import okhttp3.OkHttpClient;
11+
import okhttp3.Request;
12+
import okhttp3.Response;{{importForQuery}}{{importForBody}}{{importForFormData}}
13+
14+
import java.io.IOException;
15+
16+
public class Main {
17+
public static void main(String[] args) {
18+
OkHttpClient client = new OkHttpClient().newBuilder().build();
19+
20+
""";
21+
22+
final String kStringImportForQuery = """
23+
24+
import okhttp3.HttpUrl;""";
25+
26+
final String kStringImportForBody = """
27+
28+
import okhttp3.RequestBody;
29+
import okhttp3.MediaType;""";
30+
31+
final String kStringImportForFormData = """
32+
33+
import okhttp3.RequestBody;
34+
import okhttp3.MultipartBody;""";
35+
36+
final String kTemplateUrl = '''
37+
38+
String url = "{{url}}";
39+
40+
''';
41+
42+
final String kTemplateUrlQuery = '''
43+
44+
HttpUrl url = HttpUrl.parse("{{url}}").newBuilder()
45+
{{params}}
46+
.build();
47+
48+
''';
49+
50+
String kTemplateRequestBody = '''
51+
52+
MediaType mediaType = MediaType.parse("{{contentType}}");
53+
54+
RequestBody body = RequestBody.create({{body}}, mediaType);
55+
56+
''';
57+
58+
final String kStringRequestStart = """
59+
60+
Request request = new Request.Builder()
61+
.url(url)
62+
""";
63+
64+
final String kTemplateRequestEnd = """
65+
.{{method}}({{hasBody}})
66+
.build();
67+
68+
try (Response response = client.newCall(request).execute()) {
69+
System.out.println(response.code());
70+
if (response.body() != null) {
71+
System.out.println(response.body().string());
72+
}
73+
} catch (IOException e) {
74+
System.out.println(e.getMessage());
75+
}
76+
}
77+
}
78+
79+
""";
80+
// Converting list of form data objects to kolin multi part data
81+
String kFormDataBody = '''
82+
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
83+
{%- for item in formDataList -%}
84+
{% if item.type == 'file' %}
85+
.addFormDataPart("{{ item.name }}",null,RequestBody.create(MediaType.parse("application/octet-stream"),new File("{{ item.value }}")))
86+
{%- else %}
87+
.addFormDataPart("{{ item.name }}","{{ item.value }}")
88+
{%- endif %}
89+
{%- endfor %}
90+
.build();
91+
92+
''';
93+
94+
String? getCode(
95+
RequestModel requestModel,
96+
) {
97+
try {
98+
String result = "";
99+
bool hasQuery = false;
100+
bool hasBody = false;
101+
bool hasFormData = false;
102+
103+
var rec = getValidRequestUri(
104+
requestModel.url,
105+
requestModel.enabledRequestParams,
106+
);
107+
Uri? uri = rec.$1;
108+
109+
if (uri != null) {
110+
String url = stripUriParams(uri);
111+
112+
if (uri.hasQuery) {
113+
var params = uri.queryParameters;
114+
if (params.isNotEmpty) {
115+
hasQuery = true;
116+
var templateParams = jj.Template(kTemplateUrlQuery);
117+
result += templateParams
118+
.render({"url": url, "params": getQueryParams(params)});
119+
}
120+
}
121+
if (!hasQuery) {
122+
var templateUrl = jj.Template(kTemplateUrl);
123+
result += templateUrl.render({"url": url});
124+
}
125+
126+
var method = requestModel.method;
127+
var requestBody = requestModel.requestBody;
128+
if (requestModel.hasFormData) {
129+
hasFormData = true;
130+
var formDataTemplate = jj.Template(kFormDataBody);
131+
132+
result += formDataTemplate.render({
133+
"formDataList": requestModel.formDataMapList,
134+
});
135+
} else if (kMethodsWithBody.contains(method) && requestBody != null) {
136+
var contentLength = utf8.encode(requestBody).length;
137+
if (contentLength > 0) {
138+
hasBody = true;
139+
String contentType = requestModel.requestBodyContentType.header;
140+
var templateBody = jj.Template(kTemplateRequestBody);
141+
result += templateBody.render({
142+
"contentType": contentType,
143+
"body": kEncoder.convert(requestBody)
144+
});
145+
}
146+
}
147+
148+
var templateStart = jj.Template(kTemplateStart);
149+
var stringStart = templateStart.render({
150+
"importForQuery": hasQuery ? kStringImportForQuery : "",
151+
"importForBody": hasBody ? kStringImportForBody : "",
152+
"importForFormData": hasFormData ? kStringImportForFormData : ""
153+
});
154+
155+
result = stringStart + result;
156+
result += kStringRequestStart;
157+
158+
var headersList = requestModel.enabledRequestHeaders;
159+
if (headersList != null) {
160+
var headers = requestModel.enabledHeadersMap;
161+
if (headers.isNotEmpty) {
162+
result += getHeaders(headers);
163+
}
164+
}
165+
166+
var templateRequestEnd = jj.Template(kTemplateRequestEnd);
167+
result += templateRequestEnd.render({
168+
"method": method.name.toLowerCase(),
169+
"hasBody": (hasBody || requestModel.hasFormData) ? "body" : "",
170+
});
171+
}
172+
return result;
173+
} catch (e) {
174+
return null;
175+
}
176+
}
177+
178+
String getQueryParams(Map<String, String> params) {
179+
final paramStrings = params.entries.map((entry) => '.addQueryParameter("${entry.key}", "${entry.value}")').toList();
180+
return paramStrings.join('\n ');
181+
}
182+
183+
String getHeaders(Map<String, String> headers) {
184+
String result = "";
185+
for (final k in headers.keys) {
186+
result = """$result .addHeader("$k", "${headers[k]}")\n""";
187+
}
188+
return result;
189+
}
190+
}

lib/consts.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ enum CodegenLanguage {
272272
nodejsAxios("node.js (axios)", "javascript", "js"),
273273
nodejsFetch("node.js (fetch)", "javascript", "js"),
274274
kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"),
275+
javaOkHttp("Java (okhttp3)", "java", 'java'),
275276
pythonHttpClient("Python (http.client)", "python", "py"),
276277
pythonRequests("Python (requests)", "python", "py"),
277278
rustActix("Rust (Actix Client)", "rust", "rs"),

0 commit comments

Comments
 (0)