public abstract class ApiRequest<T> {
    
    private static final Map<String, String> id2pathMap = new ConcurrentHashMap<>();
    static {
        
    }
    
    private String apiKey;
    private String baseUrl;
    private Properties query;
    private String url;
    
    private T request;
    
    private String id;
    
    protected abstract String getApiKey();
    
    protected abstract String getBaseUrl();
    
    protected abstract Properties getQuery();
    
    protected abstract Class<?> getJsonClass();
    
    private String assembleUrl() {
        StringJoiner url = new StringJoiner("&", baseUrl + '?', "");
        for (String name : query.keySet()) {
            url.add(name + '=' + query.getProperty(name));
        }
        return url.toString();
    }
    
    public ApiRequest() {
        apiKey = getApiKey();
        query = getQuery();
        query.setProperty("key", apiKey);
        
        url = assembleUrl();
    }
    
    protected abstract T parseRequest(Reader reader);
    
    private Reader getHttpRequestReader() {
        return Internet.getBufferedReader(url);
    }
    
    private Reader getCachedRequestReader() {
        return Files.newBufferedReader(Paths.get(id2pathMap.get(id)));
    }
    
    private boolean isCached() {
        return id2pathMap.containsKey(id);
    }
    
    public T get() {
        if (request == null) {
            Reader requestReader;
            if (isCached()) {
                requestReader = getCachedRequestReader();
            } else {
                requestReader = getHttpRequestReader();
            }
            request = parseRequest(requestReader);
        }
        return request;
    }
    
}

@@ -65,89 +65,446 @@
 nal 
-Map%3CString, String%3E id2pathMap = new ConcurrentHashMap%3C%3E();%0A    static %7B%0A
+String CACHE_DIRECTORY = %22%22;%0A    private static final String ID_CACHE = CACHE_DIRECTORY + %22IDs.txt%22;%0A    private static final String CACHE_SEP = %22,%22;%0A    %0A    private static Map%3CString, String%3E getIdCache() %7B%0A        return Files.lines(ID_CACHE)%0A            .map(line -%3E line.split(CACHE_SEP))%0A            .collect(Collectors.toConcurrentMap(%0A                lineParts -%3E lineParts%5B0%5D,%0A                lineParts -%3E lineParts%5B1%5D%0A  
         
 %0A   
@@ -495,24 +495,29 @@
 %5D%0A          
+  ));
 %0A    %7D%0A    %0A
@@ -520,32 +520,112 @@
    %0A    private 
+static final Map%3CString, String%3E idCache = getIdCache();%0A    %0A    private final 
 String apiKey;%0A 
@@ -631,24 +631,30 @@
     private 
+final 
 String baseU
@@ -669,16 +669,22 @@
 private 
+final 
 Properti
@@ -701,24 +701,30 @@
     private 
+final 
 String url;%0A
@@ -732,36 +732,8 @@
    %0A
-    private T request;%0A    %0A
     
@@ -752,24 +752,52 @@
 ng id;%0A    %0A
+    private T request;%0A    %0A
     protecte
@@ -977,32 +977,163 @@
 onClass();%0A    %0A
+    private void addApiKey() %7B%0A        if (!apiKey.isEmpty()) %7B%0A            query.setProperty(%22key%22, apiKey);%0A        %7D%0A    %7D%0A    %0A
     private Stri
@@ -1472,51 +1472,21 @@
     
-query.setProperty(%22key%22, a
+addA
 piKey
+(
 );%0A
-        %0A
     
@@ -1780,24 +1780,21 @@
 s.get(id
-2pathMap
+Cache
 .get(id)
@@ -1862,16 +1862,13 @@
 n id
-2pathMap
+Cache
 .con

Update ApiRequest.java