1
resposta

[Projeto] Desafio 3 - Busca no Github com Github API

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;
}

printexit

1 resposta

E aí, Rick! Tudo bem?

Que bom ver esse esforço!

É muito positivo perceber que, mesmo diante de um desafio que exigiu bastante raciocínio, houve persistência para buscar uma solução. Isso mostra resiliência diante das dificuldades, curiosidade para aprender além do esperado e disposição de colocar em prática o que foi estudado.

Permaneça postando as suas soluções, com certeza isso ajudará outros estudantes e tem grande relevância para o fórum.

Fico à disposição! E se precisar, conte sempre com o apoio do fórum.

Abraço e bons estudos!

AluraConte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!