Functional Programming in Java, Second Edition: p.91: Rewrite FinanceData HTTP request method

On page 91, we use a short method to request a stock ticker, class FinanceData

However, this method is based on java.net.URL which has always been broken in several ways, one which being that it doesn’t encode the URL itself. That class is also deprecated in Java 20. The replacement is java.net.URI (since Java 7).

The construction of the query string, while appropriate as an exercise, can also be done better while demonstrating stream use.

Anyway, let’s go. Here is a definitely longer but IMHO nicer replacement:

    public class FinanceData {
        public static BigDecimal getPrice(final String ticker) {
            HttpResponse<String> response;
            try {
                final String scheme = "https";
                final String authority = "eodhistoricaldata.com";
                final String path = String.format("/api/eod/%s.US",ticker);
                final String query =
                        List.of("fmt=json", "filter=last_close", "api_token=OeAFFmMliFG5orCUuwAKQ8l4WWFQ67YX")
                                .stream()
                                .collect(Collectors.joining("&"));
                final String fragment = null;
                final URI uri = new URI(scheme,authority,path,query,fragment);
                System.out.println("Connecting to URI: " + uri);
                HttpClient client = HttpClient.newHttpClient();
                HttpRequest request = HttpRequest.newBuilder().uri(uri).build();
                response = client.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
            } catch(Exception ex) {
                throw new RuntimeException(ex);
            }
            System.out.println("Received status code: " + response.statusCode());
            if (response.statusCode() == 200) {
                System.out.println("Received body: " + response.body());
                // parsing BigDecimal will throw on bad syntax
                return new BigDecimal(response.body());
            }
            else {
                throw new IllegalStateException("Status code was: " + response.statusCode());
            }
        }
    }