Este desafio me meu um certo trabalho, tive de martelar um pouco a cuca para conseguir faze-lo, isso porque pedi ao ChatGPT para elaborar o desafio como se eu fosse um desenvolvedor junior(mesmo nao sendo ainda) e que o pessoal da empresa tinha deixado para mim o desafio de montar a parte de busca dos usuarios usando o Github API. O resultado final foi este:
package com.github.app;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
GithubService service = new GithubService();
System.out.println("Enter with github username:");
String username = scanner.nextLine();
GithubUser user = service.githubUser(username);
print(user);
scanner.close();
}
private static void print(@NotNull GithubUser user) {
System.out.printf(
"%n===== GitHub User =====%n" +
"Login : %s%n" +
"Name : %s%n" +
"Bio : %s%n" +
"Repos : %d%n" +
"Followers : %d%n" +
"Following : %d%n",
user.getLogin(),
user.getName(),
user.getBio(),
user.getPublicRepos(),
user.getFollowers(),
user.getFollowing()
);
}
}
package com.github.app.util;
@lombok.experimental.UtilityClass
public class JsonParser {
private final Gson gson = build();
public <T> T fromJson(@NotNull String json, Class<T> clazz) {
return gson.fromJson(json, clazz);
}
@ApiStatus.Internal
@Contract(" -> new")
private static @NotNull Gson build() {
return new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.serializeNulls()
.create();
}
}
package com.github.app.service;
public class GithubService {
private final HttpClientProvider provider = HttpClientProvider.create();
public GithubUser githubUser(@NotNull String username) {
String url = GITHUB.getUrl() + username;
if (provider.statusCode(url) == 404)
throw new ErrorGithubConsultationException("Error when consulting API, user does not found!");
var json = provider.body(url);
provider.close();
return JsonParser.fromJson(json, GithubUser.class);
}
}
package com.github.app.infra;
public record HttpClientProvider(HttpClient httpClient) implements AutoCloseable {
@Contract(" -> new")
public static @NotNull HttpClientProvider create() {
return new HttpClientProvider(HttpClient.newHttpClient());
}
public <R> R execute(String url, @NotNull Function<HttpResponse<String>, R> handler) {
try {
HttpRequest request = HttpRequest
.newBuilder(URI.create(url))
.GET()
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
return handler.apply(response);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new HttpRequestException("Thread interrupted when trying to access the URL: " + url, e);
} catch (IOException e) {
throw new HttpRequestException("Error when accessing the URL: " + url, e);
}
}
public String body(String url) {
return execute(url, HttpResponse::body);
}
public int statusCode(String url) {
return execute(url, HttpResponse::statusCode);
}
@Override
public void close() {
this.httpClient.close();
}
}
package com.github.app.exception;
public class HttpRequestException extends RuntimeException {
public HttpRequestException(String message, Throwable cause) {
super(message, cause);
}
}
package com.github.app.exception;
public class ErrorGithubConsultationException extends RuntimeException {
public ErrorGithubConsultationException(String message) {
super(message);
}
}
package com.github.app.domain;
@lombok.Data
public class GithubUser {
private String login;
private String name;
private String bio;
private int publicRepos;
private int followers;
private int following;
}
package com.github.app.api;
@lombok.RequiredArgsConstructor(lombok.AccessLevel.PRIVATE)
public enum URL {
GITHUB("https://api.github.com/users/");
@lombok.Getter(value = lombok.AccessLevel.PUBLIC)
private final String url;
}