-1

I am trying to build database - and i want to get data that i need from API which have an authentication token - im using Java, Spring, MySql DB

I've created simple example of what i want to achieve - in this example i DONT need additional header with authentication token - and my question is can i get data this way when i need to add one:

@Component
public class DataLoader implements CommandLineRunner {
    private final ObjectMapper mapper;
    private final CountryRepository repository;

    public DataLoader(ObjectMapper mapper, CountryRepository repository) {
        this.mapper = mapper;
        this.repository = repository;
    }

    @Override
    public void run(String... args) throws Exception {
        List<Country> countries = new ArrayList<>();
        JsonNode json;

        try {
            json = mapper.readValue(new URL("https://api.football-data.org/v4/areas"), JsonNode.class);
        } catch (IOException e) {
            throw new RuntimeException("Failed to read JSON data", e);
        }

        JsonNode areas = getAreas(json);

        for (JsonNode area : areas) {
            countries.add(createCountryFromNode(area));
        }

        repository.saveAll(countries);
    }

    private Country createCountryFromNode(JsonNode area) {
        String code = area.get("countryCode").asText();
        String name = area.get("name").asText();

        return new Country(code, name);
    }

    private JsonNode getAreas(JsonNode json) {
        return Optional.ofNullable(json)
                .map(j -> j.get("areas"))
                .orElseThrow(() -> new IllegalArgumentException("Invalid JSON Object"));
    }
}

So, in example above, when i use readValue() method, everything works fine, i get JSON, and i can work with it - BUT, when i want to use for example:

"https://api.football-data.org/v4/competitions/PL"

instead of:

"https://api.football-data.org/v4/areas"

my response will look like this:

"message": "The resource you are looking for is restricted and apparently not within your permissions. Please check your subscription.",
"errorCode": 403

Ive created account, i got my personal token, i got all permissions now, but i have to add this token as HTTP header.

FINALLY:

Can I add header with key token to an URL in mapper.readValue() method?

Is there any way to parse JSON by Jackson with api that have a key token? Spring annotations, anything? Or maybe i have to use "raw" Java classes (HttpRequest, HttpResponse etc.)?

1 Answer 1

1

We can't add headers using ObjectMapper. Use RestTemplate instead:

        HttpHeaders headers = new HttpHeaders();
        headers.set("X-Auth-Token", "my-new-auth-token");
        HttpEntity<String> requestEntity = new HttpEntity<>(headers);

        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.exchange("https://api.football-data.org/v4/competitions/PL", HttpMethod.GET, requestEntity, String.class);

        JsonNode json = mapper.readTree(response.getBody());

Always use restTemplate.exchange method for API calls in spring/springboot. It's simple, easy to use, supports headers, works with any http method, helps in conversion to any Java object. It has been there since ages.

Also, I would suggest you use Java class, instead of JsonNode.

public class AreaResponse {
    private List<Area> areas;
    //... getter/setters/etc
}

Create Area class & put countryCode/name parameters & instead of String.class as response type, you can provide your class AreaResponse while calling the api:

    restTemplate.exchange("https://api.football-data.org/v4/competitions/PL", HttpMethod.GET, requestEntity, AreaResponse.class)

This will even save you more boiler plate code to extract data from JsonNode object.

Sign up to request clarification or add additional context in comments.

2 Comments

One more question about last part of your answer - in your example AreaResponse class is something like AreaDTO class? Or am I mixing 2 different things?
@JuniorD It could be the DTO or entity, depends on your use-case

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.