Browse Source

Add JSON-java decoder and encoder (#1387)

* Provides decoder and encoder for JSON-java

* Rename feign-json to feign-org.json, add link to JSON web-site to README, use instanceof instead of references (JsonEncoder)

* Return back feign-json, JSON-java

* Fix parent version

* Added JSON-java decoder to decoders list

* Increase coverage: empty response body, parsing exception is caused by another exception

* Use isAssignableFrom to allow methods return extended JSONObject and JSONArray classes

Co-authored-by: Marvin Froeder <marvin.froeder@dovetailstudios.com>
pull/1455/head
Witalij Berdinskich 3 years ago committed by GitHub
parent
commit
5087bd83a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      json/README.md
  2. 69
      json/pom.xml
  3. 86
      json/src/main/java/feign/json/JsonDecoder.java
  4. 65
      json/src/main/java/feign/json/JsonEncoder.java
  5. 93
      json/src/test/java/feign/json/JsonCodecTest.java
  6. 218
      json/src/test/java/feign/json/JsonDecoderTest.java
  7. 69
      json/src/test/java/feign/json/JsonEncoderTest.java
  8. 48
      json/src/test/java/feign/json/examples/GitHubExample.java
  9. 632
      json/src/test/resources/fixtures/contributors.json
  10. 8
      pom.xml
  11. 1
      src/docs/overview-mindmap.iuml

16
json/README.md

@ -0,0 +1,16 @@
JSON-java Codec
===================
This module adds support for encoding and decoding [JSON][] via [JSON-java][].
Add `JsonEncoder` and/or `JsonDecoder` to your `Feign.Builder` like so:
```java
api = Feign.builder()
.decoder(new JsonDecoder())
.encoder(new JsonEncoder())
.target(GitHub.class, "https://api");
```
[JSON]: https://www.json.org/json-en.html
[JSON-java]: https://github.com/stleary/JSON-java

69
json/pom.xml

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2012-2021 The Feign Authors
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the License for the specific language governing permissions and limitations under
the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.github.openfeign</groupId>
<artifactId>parent</artifactId>
<version>11.3-SNAPSHOT</version>
</parent>
<artifactId>feign-json</artifactId>
<name>Feign JSON-java</name>
<description>Feign JSON-java</description>
<properties>
<main.basedir>${project.basedir}/..</main.basedir>
<hamcrest.version>1.3</hamcrest.version>
<mockito.version>1.10.19</mockito.version>
</properties>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>feign-core</artifactId>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>${hamcrest.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>${hamcrest.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>feign-mock</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

86
json/src/main/java/feign/json/JsonDecoder.java

@ -0,0 +1,86 @@
/**
* Copyright 2012-2021 The Feign Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package feign.json;
import feign.Response;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Type;
import static feign.Util.UTF_8;
import static java.lang.String.format;
/**
* Decodes responses using JSON-java.
* <p>
* Basic example with {@link feign.Feign.Builder}:
*
* <pre>
* interface GitHub {
*
* {@literal @}RequestLine("GET /repos/{owner}/{repo}/contributors")
* JSONArray contributors({@literal @}Param("owner") String owner, {@literal @}Param("repo") String repo);
*
* }
*
* GitHub github = Feign.builder()
* .decoder(new JsonDecoder())
* .target(GitHub.class, "https://api.github.com");
*
* JSONArray contributors = github.contributors("openfeign", "feign");
*
* System.out.println(contributors.getJSONObject(0).getString("login"));
* </pre>
*/
public class JsonDecoder implements Decoder {
@Override
public Object decode(Response response, Type type) throws IOException, DecodeException {
if (response.body() == null)
return null;
try (Reader reader = response.body().asReader(response.charset())) {
Reader bodyReader = (reader.markSupported()) ? reader : new BufferedReader(reader);
bodyReader.mark(1);
if (bodyReader.read() == -1) {
return null; // Empty body
}
bodyReader.reset();
return decodeJSON(response, type, bodyReader);
} catch (JSONException jsonException) {
if (jsonException.getCause() != null && jsonException.getCause() instanceof IOException) {
throw (IOException) jsonException.getCause();
}
throw new DecodeException(response.status(), jsonException.getMessage(), response.request(),
jsonException);
}
}
private Object decodeJSON(Response response, Type type, Reader reader) {
JSONTokener tokenizer = new JSONTokener(reader);
if (JSONObject.class.isAssignableFrom((Class<?>) type))
return new JSONObject(tokenizer);
else if (JSONArray.class.isAssignableFrom((Class<?>) type))
return new JSONArray(tokenizer);
else
throw new DecodeException(response.status(),
format("%s is not a type supported by this decoder.", type), response.request());
}
}

65
json/src/main/java/feign/json/JsonEncoder.java

@ -0,0 +1,65 @@
/**
* Copyright 2012-2021 The Feign Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package feign.json;
import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import org.json.JSONArray;
import org.json.JSONObject;
import java.lang.reflect.Type;
import static java.lang.String.format;
/**
* Encodes requests using JSON-java.
* <p>
* Basic example with {@link feign.Feign.Builder}:
*
* <pre>
* interface GitHub {
*
* {@literal @}RequestLine("POST /repos/{owner}/{repo}/contributors")
* JSONObject create({@literal @}Param("owner") String owner,
* {@literal @}@Param("repo") String repo,
* JSONObject contributor);
*
* }
*
* GitHub github = Feign.builder()
* .decoder(new JsonDecoder())
* .encoder(new JsonEncoder())
* .target(GitHub.class, "https://api.github.com");
*
* JSONObject contributor = new JSONObject();
*
* contributor.put("login", "radio-rogal");
* contributor.put("contributions", 0);
* github.create("openfeign", "feign", contributor);
* </pre>
*/
public class JsonEncoder implements Encoder {
@Override
public void encode(Object object, Type bodyType, RequestTemplate template)
throws EncodeException {
if (object == null)
return;
if (object instanceof JSONArray || object instanceof JSONObject) {
template.body(object.toString());
} else {
throw new EncodeException(format("%s is not a type supported by this encoder.", bodyType));
}
}
}

93
json/src/test/java/feign/json/JsonCodecTest.java

@ -0,0 +1,93 @@
/**
* Copyright 2012-2021 The Feign Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package feign.json;
import feign.Feign;
import feign.Param;
import feign.Request;
import feign.RequestLine;
import feign.mock.HttpMethod;
import feign.mock.MockClient;
import feign.mock.MockTarget;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import static feign.Util.toByteArray;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
interface GitHub {
@RequestLine("GET /repos/{owner}/{repo}/contributors")
JSONArray contributors(@Param("owner") String owner, @Param("repo") String repo);
@RequestLine("POST /repos/{owner}/{repo}/contributors")
JSONObject create(@Param("owner") String owner,
@Param("repo") String repo,
JSONObject contributor);
}
public class JsonCodecTest {
private GitHub github;
private MockClient mockClient;
@Before
public void setUp() {
mockClient = new MockClient();
github = Feign.builder()
.decoder(new JsonDecoder())
.encoder(new JsonEncoder())
.client(mockClient)
.target(new MockTarget<>(GitHub.class));
}
@Test
public void decodes() throws IOException {
try (InputStream input = getClass().getResourceAsStream("/fixtures/contributors.json")) {
byte[] response = toByteArray(input);
mockClient.ok(HttpMethod.GET, "/repos/openfeign/feign/contributors", response);
JSONArray contributors = github.contributors("openfeign", "feign");
assertThat(contributors.toList(), hasSize(30));
contributors.forEach(contributor -> ((JSONObject) contributor).getString("login"));
}
}
@Test
public void encodes() {
JSONObject contributor = new JSONObject();
contributor.put("login", "radio-rogal");
contributor.put("contributions", 0);
mockClient.ok(HttpMethod.POST, "/repos/openfeign/feign/contributors",
"{\"login\":\"radio-rogal\",\"contributions\":0}");
JSONObject response = github.create("openfeign", "feign", contributor);
Request request = mockClient.verifyOne(HttpMethod.POST, "/repos/openfeign/feign/contributors");
assertNotNull(request.body());
String json = new String(request.body());
assertThat(json, containsString("\"login\":\"radio-rogal\""));
assertThat(json, containsString("\"contributions\":0"));
assertEquals("radio-rogal", response.getString("login"));
assertEquals(0, response.getInt("contributions"));
}
}

218
json/src/test/java/feign/json/JsonDecoderTest.java

@ -0,0 +1,218 @@
/**
* Copyright 2012-2021 The Feign Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package feign.json;
import feign.Request;
import feign.Response;
import feign.codec.DecodeException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Date;
import static feign.Util.UTF_8;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class JsonDecoderTest {
private static JSONArray jsonArray;
private static JSONObject jsonObject;
private static Request request;
@BeforeClass
public static void setUpClass() {
jsonObject = new JSONObject();
jsonObject.put("a", "b");
jsonObject.put("c", 1);
jsonArray = new JSONArray();
jsonArray.put(jsonObject);
jsonArray.put(123);
request = Request.create(Request.HttpMethod.GET, "/qwerty", Collections.emptyMap(),
"xyz".getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8, null);
}
@Test
public void decodesArray() throws IOException {
String json = "[{\"a\":\"b\",\"c\":1},123]";
Response response = Response.builder()
.status(204)
.reason("OK")
.headers(Collections.emptyMap())
.body(json, UTF_8)
.request(request)
.build();
assertTrue(jsonArray.similar(new JsonDecoder().decode(response, JSONArray.class)));
}
@Test
public void decodesObject() throws IOException {
String json = "{\"a\":\"b\",\"c\":1}";
Response response = Response.builder()
.status(204)
.reason("OK")
.headers(Collections.emptyMap())
.body(json, UTF_8)
.request(request)
.build();
assertTrue(jsonObject.similar(new JsonDecoder().decode(response, JSONObject.class)));
}
@Test
public void nullBodyDecodesToNull() throws IOException {
Response response = Response.builder()
.status(204)
.reason("OK")
.headers(Collections.emptyMap())
.request(request)
.build();
assertNull(new JsonDecoder().decode(response, JSONObject.class));
}
@Test
public void emptyBodyDecodesToNull() throws IOException {
Response response = Response.builder()
.status(204)
.reason("OK")
.headers(Collections.emptyMap())
.body("", UTF_8)
.request(request)
.build();
assertNull(new JsonDecoder().decode(response, JSONObject.class));
}
@Test
public void unknownTypeThrowsDecodeException() throws IOException {
String json = "[{\"a\":\"b\",\"c\":1},123]";
Response response = Response.builder()
.status(204)
.reason("OK")
.headers(Collections.emptyMap())
.body(json, UTF_8)
.request(request)
.build();
Exception exception = assertThrows(DecodeException.class,
() -> new JsonDecoder().decode(response, Date.class));
assertEquals("class java.util.Date is not a type supported by this decoder.",
exception.getMessage());
}
@Test
public void badJsonThrowsWrappedJSONException() throws IOException {
String json = "{\"a\":\"b\",\"c\":1}";
Response response = Response.builder()
.status(204)
.reason("OK")
.headers(Collections.emptyMap())
.body(json, UTF_8)
.request(request)
.build();
Exception exception = assertThrows(DecodeException.class,
() -> new JsonDecoder().decode(response, JSONArray.class));
assertEquals("A JSONArray text must start with '[' at 1 [character 2 line 1]",
exception.getMessage());
assertTrue(exception.getCause() instanceof JSONException);
}
@Test
public void causedByCommonException() throws IOException {
Response.Body body = mock(Response.Body.class);
when(body.asReader(any())).thenThrow(new JSONException("test exception",
new Exception("test cause exception")));
Response response = Response.builder()
.status(204)
.reason("OK")
.headers(Collections.emptyMap())
.body(body)
.request(request)
.build();
Exception exception = assertThrows(DecodeException.class,
() -> new JsonDecoder().decode(response, JSONArray.class));
assertEquals("test exception", exception.getMessage());
}
@Test
public void causedByIOException() throws IOException {
Response.Body body = mock(Response.Body.class);
when(body.asReader(any())).thenThrow(new JSONException("test exception",
new IOException("test cause exception")));
Response response = Response.builder()
.status(204)
.reason("OK")
.headers(Collections.emptyMap())
.body(body)
.request(request)
.build();
Exception exception = assertThrows(IOException.class,
() -> new JsonDecoder().decode(response, JSONArray.class));
assertEquals("test cause exception", exception.getMessage());
}
@Test
public void checkedException() throws IOException {
Response.Body body = mock(Response.Body.class);
when(body.asReader(any())).thenThrow(new IOException("test exception"));
Response response = Response.builder()
.status(204)
.reason("OK")
.headers(Collections.emptyMap())
.body(body)
.request(request)
.build();
Exception exception = assertThrows(IOException.class,
() -> new JsonDecoder().decode(response, JSONArray.class));
assertEquals("test exception", exception.getMessage());
}
@Test
public void decodesExtendedArray() throws IOException {
String json = "[{\"a\":\"b\",\"c\":1},123]";
Response response = Response.builder()
.status(204)
.reason("OK")
.headers(Collections.emptyMap())
.body(json, UTF_8)
.request(request)
.build();
assertTrue(jsonArray.similar(new JsonDecoder().decode(response, ExtendedJSONArray.class)));
}
@Test
public void decodeExtendedObject() throws IOException {
String json = "{\"a\":\"b\",\"c\":1}";
Response response = Response.builder()
.status(204)
.reason("OK")
.headers(Collections.emptyMap())
.body(json, UTF_8)
.request(request)
.build();
assertTrue(jsonObject.similar(new JsonDecoder().decode(response, ExtendedJSONObject.class)));
}
static class ExtendedJSONArray extends JSONArray {
}
static class ExtendedJSONObject extends JSONObject {
}
}

69
json/src/test/java/feign/json/JsonEncoderTest.java

@ -0,0 +1,69 @@
/**
* Copyright 2012-2021 The Feign Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package feign.json;
import feign.RequestTemplate;
import feign.codec.EncodeException;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import java.util.Date;
import static feign.Util.UTF_8;
import static org.junit.Assert.*;
public class JsonEncoderTest {
private JSONArray jsonArray;
private JSONObject jsonObject;
private RequestTemplate requestTemplate;
@Before
public void setUp() {
jsonObject = new JSONObject();
jsonObject.put("a", "b");
jsonObject.put("c", 1);
jsonArray = new JSONArray();
jsonArray.put(jsonObject);
jsonArray.put(123);
requestTemplate = new RequestTemplate();
}
@Test
public void encodesArray() {
new JsonEncoder().encode(jsonArray, JSONArray.class, requestTemplate);
assertEquals("[{\"a\":\"b\",\"c\":1},123]", new String(requestTemplate.body(), UTF_8));
}
@Test
public void encodesObject() {
new JsonEncoder().encode(jsonObject, JSONObject.class, requestTemplate);
assertEquals("{\"a\":\"b\",\"c\":1}", new String(requestTemplate.body(), UTF_8));
}
@Test
public void encodesNull() {
new JsonEncoder().encode(null, JSONObject.class, new RequestTemplate());
assertNull(requestTemplate.body());
}
@Test
public void unknownTypeThrowsEncodeException() {
Exception exception = assertThrows(EncodeException.class,
() -> new JsonEncoder().encode("qwerty", Date.class, new RequestTemplate()));
assertEquals("class java.util.Date is not a type supported by this encoder.",
exception.getMessage());
}
}

48
json/src/test/java/feign/json/examples/GitHubExample.java

@ -0,0 +1,48 @@
/**
* Copyright 2012-2021 The Feign Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package feign.json.examples;
import feign.Feign;
import feign.Param;
import feign.RequestLine;
import feign.json.JsonDecoder;
import org.json.JSONArray;
import org.json.JSONObject;
interface GitHub {
@RequestLine("GET /repos/{owner}/{repo}/contributors")
JSONArray contributors(@Param("owner") String owner, @Param("repo") String repo);
}
/**
* adapted from {@code com.example.retrofit.GitHubClient}
*/
public class GitHubExample {
public static void main(String... args) {
GitHub github = Feign.builder()
.decoder(new JsonDecoder())
.target(GitHub.class, "https://api.github.com");
System.out.println("Let's fetch and print a list of the contributors to this library.");
JSONArray contributors = github.contributors("netflix", "feign");
contributors.forEach(contributor -> {
System.out.println(((JSONObject) contributor).getString("login"));
});
}
}

632
json/src/test/resources/fixtures/contributors.json

@ -0,0 +1,632 @@
[
{
"login": "kdavisk6",
"id": 6013627,
"node_id": "MDQ6VXNlcjYwMTM2Mjc=",
"avatar_url": "https://avatars.githubusercontent.com/u/6013627?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/kdavisk6",
"html_url": "https://github.com/kdavisk6",
"followers_url": "https://api.github.com/users/kdavisk6/followers",
"following_url": "https://api.github.com/users/kdavisk6/following{/other_user}",
"gists_url": "https://api.github.com/users/kdavisk6/gists{/gist_id}",
"starred_url": "https://api.github.com/users/kdavisk6/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/kdavisk6/subscriptions",
"organizations_url": "https://api.github.com/users/kdavisk6/orgs",
"repos_url": "https://api.github.com/users/kdavisk6/repos",
"events_url": "https://api.github.com/users/kdavisk6/events{/privacy}",
"received_events_url": "https://api.github.com/users/kdavisk6/received_events",
"type": "User",
"site_admin": false,
"contributions": 115
},
{
"login": "velo",
"id": 136590,
"node_id": "MDQ6VXNlcjEzNjU5MA==",
"avatar_url": "https://avatars.githubusercontent.com/u/136590?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/velo",
"html_url": "https://github.com/velo",
"followers_url": "https://api.github.com/users/velo/followers",
"following_url": "https://api.github.com/users/velo/following{/other_user}",
"gists_url": "https://api.github.com/users/velo/gists{/gist_id}",
"starred_url": "https://api.github.com/users/velo/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/velo/subscriptions",
"organizations_url": "https://api.github.com/users/velo/orgs",
"repos_url": "https://api.github.com/users/velo/repos",
"events_url": "https://api.github.com/users/velo/events{/privacy}",
"received_events_url": "https://api.github.com/users/velo/received_events",
"type": "User",
"site_admin": false,
"contributions": 98
},
{
"login": "quidryan",
"id": 360255,
"node_id": "MDQ6VXNlcjM2MDI1NQ==",
"avatar_url": "https://avatars.githubusercontent.com/u/360255?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/quidryan",
"html_url": "https://github.com/quidryan",
"followers_url": "https://api.github.com/users/quidryan/followers",
"following_url": "https://api.github.com/users/quidryan/following{/other_user}",
"gists_url": "https://api.github.com/users/quidryan/gists{/gist_id}",
"starred_url": "https://api.github.com/users/quidryan/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/quidryan/subscriptions",
"organizations_url": "https://api.github.com/users/quidryan/orgs",
"repos_url": "https://api.github.com/users/quidryan/repos",
"events_url": "https://api.github.com/users/quidryan/events{/privacy}",
"received_events_url": "https://api.github.com/users/quidryan/received_events",
"type": "User",
"site_admin": false,
"contributions": 43
},
{
"login": "snyk-bot",
"id": 19733683,
"node_id": "MDQ6VXNlcjE5NzMzNjgz",
"avatar_url": "https://avatars.githubusercontent.com/u/19733683?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/snyk-bot",
"html_url": "https://github.com/snyk-bot",
"followers_url": "https://api.github.com/users/snyk-bot/followers",
"following_url": "https://api.github.com/users/snyk-bot/following{/other_user}",
"gists_url": "https://api.github.com/users/snyk-bot/gists{/gist_id}",
"starred_url": "https://api.github.com/users/snyk-bot/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/snyk-bot/subscriptions",
"organizations_url": "https://api.github.com/users/snyk-bot/orgs",
"repos_url": "https://api.github.com/users/snyk-bot/repos",
"events_url": "https://api.github.com/users/snyk-bot/events{/privacy}",
"received_events_url": "https://api.github.com/users/snyk-bot/received_events",
"type": "User",
"site_admin": false,
"contributions": 16
},
{
"login": "rspieldenner",
"id": 782102,
"node_id": "MDQ6VXNlcjc4MjEwMg==",
"avatar_url": "https://avatars.githubusercontent.com/u/782102?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/rspieldenner",
"html_url": "https://github.com/rspieldenner",
"followers_url": "https://api.github.com/users/rspieldenner/followers",
"following_url": "https://api.github.com/users/rspieldenner/following{/other_user}",
"gists_url": "https://api.github.com/users/rspieldenner/gists{/gist_id}",
"starred_url": "https://api.github.com/users/rspieldenner/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/rspieldenner/subscriptions",
"organizations_url": "https://api.github.com/users/rspieldenner/orgs",
"repos_url": "https://api.github.com/users/rspieldenner/repos",
"events_url": "https://api.github.com/users/rspieldenner/events{/privacy}",
"received_events_url": "https://api.github.com/users/rspieldenner/received_events",
"type": "User",
"site_admin": false,
"contributions": 14
},
{
"login": "davidmc24",
"id": 447825,
"node_id": "MDQ6VXNlcjQ0NzgyNQ==",
"avatar_url": "https://avatars.githubusercontent.com/u/447825?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/davidmc24",
"html_url": "https://github.com/davidmc24",
"followers_url": "https://api.github.com/users/davidmc24/followers",
"following_url": "https://api.github.com/users/davidmc24/following{/other_user}",
"gists_url": "https://api.github.com/users/davidmc24/gists{/gist_id}",
"starred_url": "https://api.github.com/users/davidmc24/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/davidmc24/subscriptions",
"organizations_url": "https://api.github.com/users/davidmc24/orgs",
"repos_url": "https://api.github.com/users/davidmc24/repos",
"events_url": "https://api.github.com/users/davidmc24/events{/privacy}",
"received_events_url": "https://api.github.com/users/davidmc24/received_events",
"type": "User",
"site_admin": false,
"contributions": 12
},
{
"login": "ahus1",
"id": 3957921,
"node_id": "MDQ6VXNlcjM5NTc5MjE=",
"avatar_url": "https://avatars.githubusercontent.com/u/3957921?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/ahus1",
"html_url": "https://github.com/ahus1",
"followers_url": "https://api.github.com/users/ahus1/followers",
"following_url": "https://api.github.com/users/ahus1/following{/other_user}",
"gists_url": "https://api.github.com/users/ahus1/gists{/gist_id}",
"starred_url": "https://api.github.com/users/ahus1/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/ahus1/subscriptions",
"organizations_url": "https://api.github.com/users/ahus1/orgs",
"repos_url": "https://api.github.com/users/ahus1/repos",
"events_url": "https://api.github.com/users/ahus1/events{/privacy}",
"received_events_url": "https://api.github.com/users/ahus1/received_events",
"type": "User",
"site_admin": false,
"contributions": 6
},
{
"login": "carterkozak",
"id": 3854321,
"node_id": "MDQ6VXNlcjM4NTQzMjE=",
"avatar_url": "https://avatars.githubusercontent.com/u/3854321?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/carterkozak",
"html_url": "https://github.com/carterkozak",
"followers_url": "https://api.github.com/users/carterkozak/followers",
"following_url": "https://api.github.com/users/carterkozak/following{/other_user}",
"gists_url": "https://api.github.com/users/carterkozak/gists{/gist_id}",
"starred_url": "https://api.github.com/users/carterkozak/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/carterkozak/subscriptions",
"organizations_url": "https://api.github.com/users/carterkozak/orgs",
"repos_url": "https://api.github.com/users/carterkozak/repos",
"events_url": "https://api.github.com/users/carterkozak/events{/privacy}",
"received_events_url": "https://api.github.com/users/carterkozak/received_events",
"type": "User",
"site_admin": false,
"contributions": 5
},
{
"login": "spencergibb",
"id": 594085,
"node_id": "MDQ6VXNlcjU5NDA4NQ==",
"avatar_url": "https://avatars.githubusercontent.com/u/594085?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/spencergibb",
"html_url": "https://github.com/spencergibb",
"followers_url": "https://api.github.com/users/spencergibb/followers",
"following_url": "https://api.github.com/users/spencergibb/following{/other_user}",
"gists_url": "https://api.github.com/users/spencergibb/gists{/gist_id}",
"starred_url": "https://api.github.com/users/spencergibb/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/spencergibb/subscriptions",
"organizations_url": "https://api.github.com/users/spencergibb/orgs",
"repos_url": "https://api.github.com/users/spencergibb/repos",
"events_url": "https://api.github.com/users/spencergibb/events{/privacy}",
"received_events_url": "https://api.github.com/users/spencergibb/received_events",
"type": "User",
"site_admin": false,
"contributions": 5
},
{
"login": "allenxwang",
"id": 1728105,
"node_id": "MDQ6VXNlcjE3MjgxMDU=",
"avatar_url": "https://avatars.githubusercontent.com/u/1728105?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/allenxwang",
"html_url": "https://github.com/allenxwang",
"followers_url": "https://api.github.com/users/allenxwang/followers",
"following_url": "https://api.github.com/users/allenxwang/following{/other_user}",
"gists_url": "https://api.github.com/users/allenxwang/gists{/gist_id}",
"starred_url": "https://api.github.com/users/allenxwang/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/allenxwang/subscriptions",
"organizations_url": "https://api.github.com/users/allenxwang/orgs",
"repos_url": "https://api.github.com/users/allenxwang/repos",
"events_url": "https://api.github.com/users/allenxwang/events{/privacy}",
"received_events_url": "https://api.github.com/users/allenxwang/received_events",
"type": "User",
"site_admin": false,
"contributions": 5
},
{
"login": "gimbimloki",
"id": 4572139,
"node_id": "MDQ6VXNlcjQ1NzIxMzk=",
"avatar_url": "https://avatars.githubusercontent.com/u/4572139?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/gimbimloki",
"html_url": "https://github.com/gimbimloki",
"followers_url": "https://api.github.com/users/gimbimloki/followers",
"following_url": "https://api.github.com/users/gimbimloki/following{/other_user}",
"gists_url": "https://api.github.com/users/gimbimloki/gists{/gist_id}",
"starred_url": "https://api.github.com/users/gimbimloki/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/gimbimloki/subscriptions",
"organizations_url": "https://api.github.com/users/gimbimloki/orgs",
"repos_url": "https://api.github.com/users/gimbimloki/repos",
"events_url": "https://api.github.com/users/gimbimloki/events{/privacy}",
"received_events_url": "https://api.github.com/users/gimbimloki/received_events",
"type": "User",
"site_admin": false,
"contributions": 4
},
{
"login": "jkschneider",
"id": 1697736,
"node_id": "MDQ6VXNlcjE2OTc3MzY=",
"avatar_url": "https://avatars.githubusercontent.com/u/1697736?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/jkschneider",
"html_url": "https://github.com/jkschneider",
"followers_url": "https://api.github.com/users/jkschneider/followers",
"following_url": "https://api.github.com/users/jkschneider/following{/other_user}",
"gists_url": "https://api.github.com/users/jkschneider/gists{/gist_id}",
"starred_url": "https://api.github.com/users/jkschneider/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/jkschneider/subscriptions",
"organizations_url": "https://api.github.com/users/jkschneider/orgs",
"repos_url": "https://api.github.com/users/jkschneider/repos",
"events_url": "https://api.github.com/users/jkschneider/events{/privacy}",
"received_events_url": "https://api.github.com/users/jkschneider/received_events",
"type": "User",
"site_admin": false,
"contributions": 4
},
{
"login": "nmiyake",
"id": 4267425,
"node_id": "MDQ6VXNlcjQyNjc0MjU=",
"avatar_url": "https://avatars.githubusercontent.com/u/4267425?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/nmiyake",
"html_url": "https://github.com/nmiyake",
"followers_url": "https://api.github.com/users/nmiyake/followers",
"following_url": "https://api.github.com/users/nmiyake/following{/other_user}",
"gists_url": "https://api.github.com/users/nmiyake/gists{/gist_id}",
"starred_url": "https://api.github.com/users/nmiyake/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/nmiyake/subscriptions",
"organizations_url": "https://api.github.com/users/nmiyake/orgs",
"repos_url": "https://api.github.com/users/nmiyake/repos",
"events_url": "https://api.github.com/users/nmiyake/events{/privacy}",
"received_events_url": "https://api.github.com/users/nmiyake/received_events",
"type": "User",
"site_admin": false,
"contributions": 4
},
{
"login": "rfalke",
"id": 1261007,
"node_id": "MDQ6VXNlcjEyNjEwMDc=",
"avatar_url": "https://avatars.githubusercontent.com/u/1261007?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/rfalke",
"html_url": "https://github.com/rfalke",
"followers_url": "https://api.github.com/users/rfalke/followers",
"following_url": "https://api.github.com/users/rfalke/following{/other_user}",
"gists_url": "https://api.github.com/users/rfalke/gists{/gist_id}",
"starred_url": "https://api.github.com/users/rfalke/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/rfalke/subscriptions",
"organizations_url": "https://api.github.com/users/rfalke/orgs",
"repos_url": "https://api.github.com/users/rfalke/repos",
"events_url": "https://api.github.com/users/rfalke/events{/privacy}",
"received_events_url": "https://api.github.com/users/rfalke/received_events",
"type": "User",
"site_admin": false,
"contributions": 4
},
{
"login": "SimY4",
"id": 1394639,
"node_id": "MDQ6VXNlcjEzOTQ2Mzk=",
"avatar_url": "https://avatars.githubusercontent.com/u/1394639?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/SimY4",
"html_url": "https://github.com/SimY4",
"followers_url": "https://api.github.com/users/SimY4/followers",
"following_url": "https://api.github.com/users/SimY4/following{/other_user}",
"gists_url": "https://api.github.com/users/SimY4/gists{/gist_id}",
"starred_url": "https://api.github.com/users/SimY4/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/SimY4/subscriptions",
"organizations_url": "https://api.github.com/users/SimY4/orgs",
"repos_url": "https://api.github.com/users/SimY4/repos",
"events_url": "https://api.github.com/users/SimY4/events{/privacy}",
"received_events_url": "https://api.github.com/users/SimY4/received_events",
"type": "User",
"site_admin": false,
"contributions": 3
},
{
"login": "bstick12",
"id": 1146861,
"node_id": "MDQ6VXNlcjExNDY4NjE=",
"avatar_url": "https://avatars.githubusercontent.com/u/1146861?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/bstick12",
"html_url": "https://github.com/bstick12",
"followers_url": "https://api.github.com/users/bstick12/followers",
"following_url": "https://api.github.com/users/bstick12/following{/other_user}",
"gists_url": "https://api.github.com/users/bstick12/gists{/gist_id}",
"starred_url": "https://api.github.com/users/bstick12/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/bstick12/subscriptions",
"organizations_url": "https://api.github.com/users/bstick12/orgs",
"repos_url": "https://api.github.com/users/bstick12/repos",
"events_url": "https://api.github.com/users/bstick12/events{/privacy}",
"received_events_url": "https://api.github.com/users/bstick12/received_events",
"type": "User",
"site_admin": false,
"contributions": 3
},
{
"login": "mstrYoda",
"id": 12763626,
"node_id": "MDQ6VXNlcjEyNzYzNjI2",
"avatar_url": "https://avatars.githubusercontent.com/u/12763626?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/mstrYoda",
"html_url": "https://github.com/mstrYoda",
"followers_url": "https://api.github.com/users/mstrYoda/followers",
"following_url": "https://api.github.com/users/mstrYoda/following{/other_user}",
"gists_url": "https://api.github.com/users/mstrYoda/gists{/gist_id}",
"starred_url": "https://api.github.com/users/mstrYoda/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/mstrYoda/subscriptions",
"organizations_url": "https://api.github.com/users/mstrYoda/orgs",
"repos_url": "https://api.github.com/users/mstrYoda/repos",
"events_url": "https://api.github.com/users/mstrYoda/events{/privacy}",
"received_events_url": "https://api.github.com/users/mstrYoda/received_events",
"type": "User",
"site_admin": false,
"contributions": 3
},
{
"login": "jacob-meacham",
"id": 1624811,
"node_id": "MDQ6VXNlcjE2MjQ4MTE=",
"avatar_url": "https://avatars.githubusercontent.com/u/1624811?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/jacob-meacham",
"html_url": "https://github.com/jacob-meacham",
"followers_url": "https://api.github.com/users/jacob-meacham/followers",
"following_url": "https://api.github.com/users/jacob-meacham/following{/other_user}",
"gists_url": "https://api.github.com/users/jacob-meacham/gists{/gist_id}",
"starred_url": "https://api.github.com/users/jacob-meacham/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/jacob-meacham/subscriptions",
"organizations_url": "https://api.github.com/users/jacob-meacham/orgs",
"repos_url": "https://api.github.com/users/jacob-meacham/repos",
"events_url": "https://api.github.com/users/jacob-meacham/events{/privacy}",
"received_events_url": "https://api.github.com/users/jacob-meacham/received_events",
"type": "User",
"site_admin": false,
"contributions": 3
},
{
"login": "pnepywoda",
"id": 13909400,
"node_id": "MDQ6VXNlcjEzOTA5NDAw",
"avatar_url": "https://avatars.githubusercontent.com/u/13909400?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/pnepywoda",
"html_url": "https://github.com/pnepywoda",
"followers_url": "https://api.github.com/users/pnepywoda/followers",
"following_url": "https://api.github.com/users/pnepywoda/following{/other_user}",
"gists_url": "https://api.github.com/users/pnepywoda/gists{/gist_id}",
"starred_url": "https://api.github.com/users/pnepywoda/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/pnepywoda/subscriptions",
"organizations_url": "https://api.github.com/users/pnepywoda/orgs",
"repos_url": "https://api.github.com/users/pnepywoda/repos",
"events_url": "https://api.github.com/users/pnepywoda/events{/privacy}",
"received_events_url": "https://api.github.com/users/pnepywoda/received_events",
"type": "User",
"site_admin": false,
"contributions": 3
},
{
"login": "santhosh-tekuri",
"id": 1112271,
"node_id": "MDQ6VXNlcjExMTIyNzE=",
"avatar_url": "https://avatars.githubusercontent.com/u/1112271?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/santhosh-tekuri",
"html_url": "https://github.com/santhosh-tekuri",
"followers_url": "https://api.github.com/users/santhosh-tekuri/followers",
"following_url": "https://api.github.com/users/santhosh-tekuri/following{/other_user}",
"gists_url": "https://api.github.com/users/santhosh-tekuri/gists{/gist_id}",
"starred_url": "https://api.github.com/users/santhosh-tekuri/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/santhosh-tekuri/subscriptions",
"organizations_url": "https://api.github.com/users/santhosh-tekuri/orgs",
"repos_url": "https://api.github.com/users/santhosh-tekuri/repos",
"events_url": "https://api.github.com/users/santhosh-tekuri/events{/privacy}",
"received_events_url": "https://api.github.com/users/santhosh-tekuri/received_events",
"type": "User",
"site_admin": false,
"contributions": 3
},
{
"login": "jerzykrlk",
"id": 4005877,
"node_id": "MDQ6VXNlcjQwMDU4Nzc=",
"avatar_url": "https://avatars.githubusercontent.com/u/4005877?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/jerzykrlk",
"html_url": "https://github.com/jerzykrlk",
"followers_url": "https://api.github.com/users/jerzykrlk/followers",
"following_url": "https://api.github.com/users/jerzykrlk/following{/other_user}",
"gists_url": "https://api.github.com/users/jerzykrlk/gists{/gist_id}",
"starred_url": "https://api.github.com/users/jerzykrlk/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/jerzykrlk/subscriptions",
"organizations_url": "https://api.github.com/users/jerzykrlk/orgs",
"repos_url": "https://api.github.com/users/jerzykrlk/repos",
"events_url": "https://api.github.com/users/jerzykrlk/events{/privacy}",
"received_events_url": "https://api.github.com/users/jerzykrlk/received_events",
"type": "User",
"site_admin": false,
"contributions": 3
},
{
"login": "benmanbs",
"id": 1074810,
"node_id": "MDQ6VXNlcjEwNzQ4MTA=",
"avatar_url": "https://avatars.githubusercontent.com/u/1074810?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/benmanbs",
"html_url": "https://github.com/benmanbs",
"followers_url": "https://api.github.com/users/benmanbs/followers",
"following_url": "https://api.github.com/users/benmanbs/following{/other_user}",
"gists_url": "https://api.github.com/users/benmanbs/gists{/gist_id}",
"starred_url": "https://api.github.com/users/benmanbs/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/benmanbs/subscriptions",
"organizations_url": "https://api.github.com/users/benmanbs/orgs",
"repos_url": "https://api.github.com/users/benmanbs/repos",
"events_url": "https://api.github.com/users/benmanbs/events{/privacy}",
"received_events_url": "https://api.github.com/users/benmanbs/received_events",
"type": "User",
"site_admin": false,
"contributions": 2
},
{
"login": "schlosna",
"id": 54594,
"node_id": "MDQ6VXNlcjU0NTk0",
"avatar_url": "https://avatars.githubusercontent.com/u/54594?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/schlosna",
"html_url": "https://github.com/schlosna",
"followers_url": "https://api.github.com/users/schlosna/followers",
"following_url": "https://api.github.com/users/schlosna/following{/other_user}",
"gists_url": "https://api.github.com/users/schlosna/gists{/gist_id}",
"starred_url": "https://api.github.com/users/schlosna/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/schlosna/subscriptions",
"organizations_url": "https://api.github.com/users/schlosna/orgs",
"repos_url": "https://api.github.com/users/schlosna/repos",
"events_url": "https://api.github.com/users/schlosna/events{/privacy}",
"received_events_url": "https://api.github.com/users/schlosna/received_events",
"type": "User",
"site_admin": false,
"contributions": 2
},
{
"login": "dharmeshjogadia",
"id": 6071120,
"node_id": "MDQ6VXNlcjYwNzExMjA=",
"avatar_url": "https://avatars.githubusercontent.com/u/6071120?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/dharmeshjogadia",
"html_url": "https://github.com/dharmeshjogadia",
"followers_url": "https://api.github.com/users/dharmeshjogadia/followers",
"following_url": "https://api.github.com/users/dharmeshjogadia/following{/other_user}",
"gists_url": "https://api.github.com/users/dharmeshjogadia/gists{/gist_id}",
"starred_url": "https://api.github.com/users/dharmeshjogadia/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/dharmeshjogadia/subscriptions",
"organizations_url": "https://api.github.com/users/dharmeshjogadia/orgs",
"repos_url": "https://api.github.com/users/dharmeshjogadia/repos",
"events_url": "https://api.github.com/users/dharmeshjogadia/events{/privacy}",
"received_events_url": "https://api.github.com/users/dharmeshjogadia/received_events",
"type": "User",
"site_admin": false,
"contributions": 2
},
{
"login": "edio",
"id": 787439,
"node_id": "MDQ6VXNlcjc4NzQzOQ==",
"avatar_url": "https://avatars.githubusercontent.com/u/787439?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/edio",
"html_url": "https://github.com/edio",
"followers_url": "https://api.github.com/users/edio/followers",
"following_url": "https://api.github.com/users/edio/following{/other_user}",
"gists_url": "https://api.github.com/users/edio/gists{/gist_id}",
"starred_url": "https://api.github.com/users/edio/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/edio/subscriptions",
"organizations_url": "https://api.github.com/users/edio/orgs",
"repos_url": "https://api.github.com/users/edio/repos",
"events_url": "https://api.github.com/users/edio/events{/privacy}",
"received_events_url": "https://api.github.com/users/edio/received_events",
"type": "User",
"site_admin": false,
"contributions": 2
},
{
"login": "androidfred",
"id": 870822,
"node_id": "MDQ6VXNlcjg3MDgyMg==",
"avatar_url": "https://avatars.githubusercontent.com/u/870822?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/androidfred",
"html_url": "https://github.com/androidfred",
"followers_url": "https://api.github.com/users/androidfred/followers",
"following_url": "https://api.github.com/users/androidfred/following{/other_user}",
"gists_url": "https://api.github.com/users/androidfred/gists{/gist_id}",
"starred_url": "https://api.github.com/users/androidfred/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/androidfred/subscriptions",
"organizations_url": "https://api.github.com/users/androidfred/orgs",
"repos_url": "https://api.github.com/users/androidfred/repos",
"events_url": "https://api.github.com/users/androidfred/events{/privacy}",
"received_events_url": "https://api.github.com/users/androidfred/received_events",
"type": "User",
"site_admin": false,
"contributions": 2
},
{
"login": "stromnet",
"id": 668449,
"node_id": "MDQ6VXNlcjY2ODQ0OQ==",
"avatar_url": "https://avatars.githubusercontent.com/u/668449?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/stromnet",
"html_url": "https://github.com/stromnet",
"followers_url": "https://api.github.com/users/stromnet/followers",
"following_url": "https://api.github.com/users/stromnet/following{/other_user}",
"gists_url": "https://api.github.com/users/stromnet/gists{/gist_id}",
"starred_url": "https://api.github.com/users/stromnet/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/stromnet/subscriptions",
"organizations_url": "https://api.github.com/users/stromnet/orgs",
"repos_url": "https://api.github.com/users/stromnet/repos",
"events_url": "https://api.github.com/users/stromnet/events{/privacy}",
"received_events_url": "https://api.github.com/users/stromnet/received_events",
"type": "User",
"site_admin": false,
"contributions": 2
},
{
"login": "JonathanO",
"id": 1206546,
"node_id": "MDQ6VXNlcjEyMDY1NDY=",
"avatar_url": "https://avatars.githubusercontent.com/u/1206546?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/JonathanO",
"html_url": "https://github.com/JonathanO",
"followers_url": "https://api.github.com/users/JonathanO/followers",
"following_url": "https://api.github.com/users/JonathanO/following{/other_user}",
"gists_url": "https://api.github.com/users/JonathanO/gists{/gist_id}",
"starred_url": "https://api.github.com/users/JonathanO/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/JonathanO/subscriptions",
"organizations_url": "https://api.github.com/users/JonathanO/orgs",
"repos_url": "https://api.github.com/users/JonathanO/repos",
"events_url": "https://api.github.com/users/JonathanO/events{/privacy}",
"received_events_url": "https://api.github.com/users/JonathanO/received_events",
"type": "User",
"site_admin": false,
"contributions": 2
},
{
"login": "finnetrolle",
"id": 6028373,
"node_id": "MDQ6VXNlcjYwMjgzNzM=",
"avatar_url": "https://avatars.githubusercontent.com/u/6028373?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/finnetrolle",
"html_url": "https://github.com/finnetrolle",
"followers_url": "https://api.github.com/users/finnetrolle/followers",
"following_url": "https://api.github.com/users/finnetrolle/following{/other_user}",
"gists_url": "https://api.github.com/users/finnetrolle/gists{/gist_id}",
"starred_url": "https://api.github.com/users/finnetrolle/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/finnetrolle/subscriptions",
"organizations_url": "https://api.github.com/users/finnetrolle/orgs",
"repos_url": "https://api.github.com/users/finnetrolle/repos",
"events_url": "https://api.github.com/users/finnetrolle/events{/privacy}",
"received_events_url": "https://api.github.com/users/finnetrolle/received_events",
"type": "User",
"site_admin": false,
"contributions": 2
},
{
"login": "padilo",
"id": 783959,
"node_id": "MDQ6VXNlcjc4Mzk1OQ==",
"avatar_url": "https://avatars.githubusercontent.com/u/783959?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/padilo",
"html_url": "https://github.com/padilo",
"followers_url": "https://api.github.com/users/padilo/followers",
"following_url": "https://api.github.com/users/padilo/following{/other_user}",
"gists_url": "https://api.github.com/users/padilo/gists{/gist_id}",
"starred_url": "https://api.github.com/users/padilo/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/padilo/subscriptions",
"organizations_url": "https://api.github.com/users/padilo/orgs",
"repos_url": "https://api.github.com/users/padilo/repos",
"events_url": "https://api.github.com/users/padilo/events{/privacy}",
"received_events_url": "https://api.github.com/users/padilo/received_events",
"type": "User",
"site_admin": false,
"contributions": 2
}
]

8
pom.xml

@ -37,6 +37,7 @@
<module>jaxb</module> <module>jaxb</module>
<module>jaxrs</module> <module>jaxrs</module>
<module>jaxrs2</module> <module>jaxrs2</module>
<module>json</module>
<module>okhttp</module> <module>okhttp</module>
<module>googlehttpclient</module> <module>googlehttpclient</module>
<module>ribbon</module> <module>ribbon</module>
@ -78,6 +79,7 @@
<gson.version>2.8.7</gson.version> <gson.version>2.8.7</gson.version>
<slf4j.version>1.7.30</slf4j.version> <slf4j.version>1.7.30</slf4j.version>
<bouncy.version>1.60</bouncy.version> <bouncy.version>1.60</bouncy.version>
<json.version>20210307</json.version>
<junit.version>4.13.1</junit.version> <junit.version>4.13.1</junit.version>
<jackson.version>2.12.3</jackson.version> <jackson.version>2.12.3</jackson.version>
@ -320,6 +322,12 @@
<version>${bouncy.version}</version> <version>${bouncy.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${json.version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>

1
src/docs/overview-mindmap.iuml

@ -26,6 +26,7 @@
*** Jackson JAXB *** Jackson JAXB
*** Jackson Jr *** Jackson Jr
*** Sax *** Sax
*** JSON-java
** metrics ** metrics
*** Dropwizard Metrics 5 *** Dropwizard Metrics 5
*** Micrometer *** Micrometer

Loading…
Cancel
Save