Jak korzystać z GitHub API


Jak korzystać z GitHub API

GitHub wystawia własne API które dostarcza wielu cennych informacji o repozytoriach. W artykule tym wystawimy własne API które z użyciem API GitHuba dostarczy informacji o konkretnym repozytorium. Zaczynamy od nowego projektu Spring Boot – niezbędne zależności – plik pom.xml:

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter</artifactId>
	</dependency>
 
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
 
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
 
	<dependency>
		<groupId>com.google.code.gson</groupId>
		<artifactId>gson</artifactId>
		<version>2.8.5</version>
	</dependency>
 
	<dependency>
		<groupId>org.apache.httpcomponents</groupId>
		<artifactId>httpclient</artifactId>
		<version>4.3.6</version>
	</dependency>
 
	<dependency>
		<groupId>one.util</groupId>
		<artifactId>streamex</artifactId>
		<version>0.6.5</version>
	</dependency>
</dependencies>

Tworzymy model – GitHubEntity:

public class GitHubEntity {
 
    @JsonProperty("fullName")
    private String nameOfRepository;
 
    @JsonProperty("description")
    private String descriptionOfRepository;
 
    @JsonProperty("cloneUrl")
    private String gitCloneUrlRepository;
 
    @JsonProperty("stars")
    private Integer numberOfStargazerRepository;
 
    @JsonProperty("createdAt")
    private String dateOfCreationRepository;
 
   // setters & getters
}

RestController – wystawiamy własne API i korzystamy z biblioteki gson:

@RestController
@RequestMapping("/repositories")
public class GithubControllerRestApiController {
 
    @RequestMapping("/{owner}/{repositoryName}")
    public ResponseEntity<?> getRepoDetailsByOwner(@PathVariable String owner, @PathVariable String repositoryName) {
 
        final String FULL_NAME    = "full_name";
        final String DESCRIPTION  = "description";
        final String CLONE_URL    = "clone_url";
        final String CREATED_AT   = "created_at";
 
        Map map = getMapFromJson(githubWrapperRepo(owner,repositoryName));
 
        String fullNameRepo    = map.get(FULL_NAME).toString();
        String descriptionRepo = map.get(DESCRIPTION).toString();
        String cloneUrlRepo    = map.get(CLONE_URL).toString();
        String createdDateRepo = map.get(CREATED_AT).toString();
 
        int stars              = githubWrapperStarGazersQuantity(owner,repositoryName);
 
        return new ResponseEntity(createModel(fullNameRepo,descriptionRepo,cloneUrlRepo,createdDateRepo, stars), HttpStatus.OK);
 
    }
 
    private int githubWrapperStarGazersQuantity(String user, String repo) {
 
        HttpEntity<String> entity = new HttpEntity("parameters", GitHubHelper.getUserAgentHeader());
 
        RestTemplate rest               = new RestTemplate();
        ResponseEntity<String> exchange = rest.exchange(
                "https://api.github.com/repos/" + user + "/" + repo + "/stargazers",
                HttpMethod.GET,
                entity,
                String.class);
 
        return getGson().fromJson(exchange.getBody(), Map[] .class).length;
 
    }
 
    private String githubWrapperRepo(String user, String repo) {
 
        HttpEntity<String> entity = new HttpEntity("parameters", GitHubHelper.getUserAgentHeader());
 
        RestTemplate rest               = new RestTemplate();
        ResponseEntity<String> exchange = rest.exchange(
                "https://api.github.com/repos/" + user + "/" + repo,
                HttpMethod.GET,
                entity,
                String.class);
 
        return exchange.getBody();
    }
 
    private Gson getGson() {
        return new Gson();
    }
 
    private Map getMapFromJson(String jsonString) {
        return getGson().fromJson(jsonString, Map.class);
    }
 
    private GitHubEntity createModel(String fullNameRepo,String descriptionRepo, String cloneUrlRepo, String createdDateRepo, int stars) {
 
        GitHubEntity gitHubEntity = new GitHubEntity();
 
        gitHubEntity.setNameOfRepository(fullNameRepo);
        gitHubEntity.setDescriptionOfRepository(descriptionRepo);
        gitHubEntity.setGitCloneUrlRepository(cloneUrlRepo);
        gitHubEntity.setNumberOfStargazerRepository(stars);
        gitHubEntity.setDateOfCreationRepository(createLocalDate(createdDateRepo));
 
        return gitHubEntity;
    }
 
    private String createLocalDate(String createdDateRepo) {
        ZonedDateTime zonedDateTime = ZonedDateTime.parse(createdDateRepo);
        return zonedDateTime.toLocalDate().toString();
    }
}

Odpowiedni Helper który doda nagłówek User-Agent co jest wymagane przez API GitHuba:

public class GitHubHelper {
    public static HttpHeaders getUserAgentHeader() {
        HttpHeaders headers = new HttpHeaders();
        headers.add("User-Agent", "http://developer.github.com/v3/#user-agent-required");
        return headers;
    }
}

Mapowanie wyniku żądania na model:

public class RetrieveUtil {
 
    public static <T> T retrieveResourceFromResponse(HttpResponse response, Class<T> clazz)
            throws IOException {
 
        String jsonFromResponse = EntityUtils.toString(response.getEntity());
        ObjectMapper mapper = new ObjectMapper()
                .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        return mapper.readValue(jsonFromResponse, clazz);
    }
 
}

Testy jednostkowe – spring-boot-starter-test. Weryfikujemy status odpowiedzi oraz weryfikujemy nazwę repozytorium:

@RunWith(SpringRunner.class)
@SpringBootTest
public class GithubRestWrapperApiApplicationTests {
 
	@Test
	public void contextLoads() {
	}
 
	@Test
	public void checkStatusCode() throws IOException {
 
		// Given
		HttpUriRequest request = new HttpGet( "http://localhost:8080//repositories/mwarycha/SpringMVC4");
 
		// When
		HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request);
 
		// Then
		assertThat(httpResponse.getStatusLine().getStatusCode(), equalTo(HttpStatus.SC_OK));
	}
 
    @Test
	public void checkNameOfRepository() throws IOException {
 
        // Given
        HttpUriRequest request = new HttpGet( "http://localhost:8080//repositories/mwarycha/SpringMVC4" );
 
        // When
        HttpResponse response = HttpClientBuilder.create().build().execute( request );
 
        // Then
        GitHubEntity resource = RetrieveUtil.retrieveResourceFromResponse(response, GitHubEntity.class);
        assertThat( "mwarycha/SpringMVC4", Matchers.is(resource.getNameOfRepository()));
    }
 
}

Wyniki testów:

[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  22.607 s
[INFO] Finished at: 2019-07-30T17:52:29+02:00
[INFO] ------------------------------------------------------------------------


Leave a comment

Your email address will not be published.


*