View Javadoc
1   package com.guinetik.examples;
2   
3   import com.guinetik.rr.RocketRest;
4   import com.guinetik.rr.RocketRestConfig;
5   import com.guinetik.rr.RocketRestOptions;
6   import com.guinetik.rr.result.ApiError;
7   import com.guinetik.rr.result.Result;
8   
9   import java.time.LocalDate;
10  import java.time.format.DateTimeFormatter;
11  import java.util.HashMap;
12  import java.util.Map;
13  import java.util.Scanner;
14  
15  /**
16   * Example demonstrating how to fetch NASA's Astronomy Picture of the Day (APOD)
17   * using RocketRest's fluent API.
18   * API documentation: https://api.nasa.gov/
19   */
20  public class NasaApodExample implements Example {
21      
22      private static final String NASA_API_BASE_URL = "https://api.nasa.gov";
23      private static final String DEFAULT_API_KEY = "DEMO_KEY";
24      
25      @Override
26      public String getName() {
27          return "NASA Astronomy Picture of the Day (APOD) API";
28      }
29      
30      @Override
31      public void run() {
32          System.out.println("====================================");
33          System.out.println("NASA Astronomy Picture of the Day API");
34          System.out.println("====================================");
35          System.out.println("This example fetches the NASA APOD using RocketRest's fluent API.");
36          System.out.println("The DEMO_KEY has strict usage limits. Get your free API key at: https://api.nasa.gov/");
37          
38          // Prompt for API key
39          String apiKey = promptForApiKey();
40          
41          // Create RocketRest client for NASA API
42          RocketRestConfig config = RocketRestConfig.builder(NASA_API_BASE_URL)
43                  .defaultOptions(options -> {
44                      // Set logging options
45                      options.set(RocketRestOptions.LOGGING_ENABLED, true);
46                      options.set(RocketRestOptions.LOG_RESPONSE_BODY, true);
47                  })
48                  .build();
49          
50          RocketRest client = new RocketRest(NASA_API_BASE_URL, config);
51          
52          try {
53              // Optional: Get specific date or use today
54              LocalDate date = promptForDate();
55              
56              // Build query parameters
57              Map<String, String> queryParams = new HashMap<>();
58              queryParams.put("api_key", apiKey);
59              
60              // Add date parameter if user selected a specific date
61              if (date != null) {
62                  String formattedDate = date.format(DateTimeFormatter.ISO_DATE);
63                  queryParams.put("date", formattedDate);
64                  System.out.println("\nFetching APOD for date: " + formattedDate);
65              } else {
66                  System.out.println("\nFetching today's APOD");
67              }
68              
69              // Display raw response data from API for debugging
70              System.out.println("\nMaking request to: " + NASA_API_BASE_URL + "/planetary/apod with params: " + queryParams);
71              
72              // Using the fluent API to handle success/error cases elegantly
73              Result<ApodResponse, ApiError> result = client.fluent()
74                      .get("/planetary/apod", ApodResponse.class, queryParams);
75              
76              // Process the result
77              result.ifSuccess(this::displayApodInfo)
78                    .ifFailure(this::handleApiError);
79                    
80          } catch (Exception e) {
81              System.out.println("āŒ Error: " + e.getMessage());
82              e.printStackTrace();
83          } finally {
84              client.shutdown();
85          }
86      }
87      
88      /**
89       * Prompts the user to enter their NASA API key or use the default DEMO_KEY
90       */
91      private String promptForApiKey() {
92          Scanner scanner = new Scanner(System.in);
93          System.out.print("\nEnter your NASA API key (or press Enter to use DEMO_KEY): ");
94          String key = scanner.nextLine().trim();
95          
96          // Use default if empty
97          if (key.isEmpty()) {
98              System.out.println("Using default DEMO_KEY");
99              return DEFAULT_API_KEY;
100         }
101         
102         return key;
103     }
104     
105     /**
106      * Prompts the user to enter a specific date or use today's date
107      */
108     private LocalDate promptForDate() {
109         Scanner scanner = new Scanner(System.in);
110         System.out.print("\nEnter a date (YYYY-MM-DD) or press Enter for today's picture: ");
111         String dateStr = scanner.nextLine().trim();
112         
113         // Return null if empty (will use today's date)
114         if (dateStr.isEmpty()) {
115             return null;
116         }
117         
118         try {
119             return LocalDate.parse(dateStr);
120         } catch (Exception e) {
121             System.out.println("Invalid date format. Using today's date instead.");
122             return null;
123         }
124     }
125     
126     /**
127      * Displays information about the Astronomy Picture of the Day
128      */
129     private void displayApodInfo(ApodResponse apod) {
130         System.out.println("\n==== Astronomy Picture of the Day ====");
131         System.out.println("Date: " + apod.getDate());
132         System.out.println("Title: " + apod.getTitle());
133         
134         // Add null checks to avoid NullPointerException
135         String mediaType = apod.getMediaType();
136         System.out.println("Media Type: " + (mediaType != null ? mediaType : "unknown"));
137         
138         // Safe handling of media type
139         if (mediaType != null) {
140             if ("image".equals(mediaType)) {
141                 System.out.println("\nImage URL: " + apod.getUrl());
142                 if (apod.getHdurl() != null) {
143                     System.out.println("HD Image URL: " + apod.getHdurl());
144                 }
145             } else if ("video".equals(mediaType)) {
146                 System.out.println("\nVideo URL: " + apod.getUrl());
147             } else {
148                 // Unknown media type, show URL anyway
149                 System.out.println("\nURL: " + apod.getUrl());
150             }
151         } else {
152             // If media_type is missing, show URL anyway
153             if (apod.getUrl() != null) {
154                 System.out.println("\nURL: " + apod.getUrl());
155             }
156         }
157         
158         if (apod.getExplanation() != null) {
159             System.out.println("\nExplanation:");
160             System.out.println(apod.getExplanation());
161         }
162         
163         if (apod.getCopyright() != null && !apod.getCopyright().isEmpty()) {
164             System.out.println("\nCopyright: " + apod.getCopyright());
165         }
166         
167         // Debug - print all fields to help diagnose serialization issues
168         System.out.println("\n--- Debug Info ---");
169         System.out.println("Raw media_type value: " + apod.media_type);
170         System.out.println("Raw url value: " + apod.url);
171         System.out.println("Raw hdurl value: " + apod.hdurl);
172     }
173     
174     /**
175      * Handles API errors
176      */
177     private void handleApiError(ApiError error) {
178         System.out.println("\nāŒ API Error:");
179         System.out.println("Status: " + error.getStatusCode());
180         System.out.println("Message: " + error.getMessage());
181         
182         if (error.getStatusCode() == 403) {
183             System.out.println("\nTip: You might be exceeding the rate limits of DEMO_KEY.");
184             System.out.println("Get your free API key at: https://api.nasa.gov/");
185         } else if (error.getStatusCode() == 429) {
186             System.out.println("\nTip: You've hit the rate limit. Please try again later.");
187         }
188     }
189     
190     /**
191      * POJO class representing the NASA APOD API response
192      */
193     public static class ApodResponse {
194         // Use public fields for direct access in a debug section
195         public String date;
196         public String explanation;
197         public String hdurl;
198         public String media_type;
199         public String service_version;
200         public String title;
201         public String url;
202         public String copyright;
203         
204         // Required empty constructor for deserialization
205         public ApodResponse() {
206         }
207         
208         // Getters and setters
209         public String getDate() {
210             return date;
211         }
212         
213         public void setDate(String date) {
214             this.date = date;
215         }
216         
217         public String getExplanation() {
218             return explanation;
219         }
220         
221         public void setExplanation(String explanation) {
222             this.explanation = explanation;
223         }
224         
225         public String getHdurl() {
226             return hdurl;
227         }
228         
229         public void setHdurl(String hdurl) {
230             this.hdurl = hdurl;
231         }
232         
233         public String getMediaType() {
234             return media_type;  // This getter needs to return media_type field
235         }
236         
237         public void setMediaType(String mediaType) {
238             this.media_type = mediaType;
239         }
240         
241         public String getServiceVersion() {
242             return service_version;
243         }
244         
245         public void setServiceVersion(String serviceVersion) {
246             this.service_version = serviceVersion;
247         }
248         
249         public String getTitle() {
250             return title;
251         }
252         
253         public void setTitle(String title) {
254             this.title = title;
255         }
256         
257         public String getUrl() {
258             return url;
259         }
260         
261         public void setUrl(String url) {
262             this.url = url;
263         }
264         
265         public String getCopyright() {
266             return copyright;
267         }
268         
269         public void setCopyright(String copyright) {
270             this.copyright = copyright;
271         }
272         
273         @Override
274         public String toString() {
275             return "ApodResponse{" +
276                     "date='" + date + '\'' +
277                     ", title='" + title + '\'' +
278                     ", media_type='" + media_type + '\'' +
279                     ", url='" + url + '\'' +
280                     '}';
281         }
282     }
283 }