What is this?
This is a JVM
(Java
, Kotlin
) and Android
library, implementing the API of the Proxer.Me website. This is currently v1
. Built on Retrofit, OkHttp and Moshi, it offers great performance and flexibility.
Including in your project
The preferred build system is Gradle.
Add this to your project wide build.gradle:
repositories {
maven { url "https://jitpack.io" }
}
And this to your module build.gradle:
dependencies {
implementation 'com.github.proxer:ProxerLibJava:5.3.0'
}
You can also download the jar
directly
from here, if you prefer.
Note that this jar does not come with the required dependencies. You have to include those manually in that case.
Usage
Initialization
All requests are done through the ProxerApi
class. You initialize an instance with the ProxerApi.Builder
.
The most simple initialization looks like this:
ProxerApi api = new ProxerApi.Builder("yourApiKey").build();
You can customize the ProxerApi
in the following ways:
Method | Description |
---|---|
loginTokenManager |
Sets an own LoginTokenManager for automatic login. This will covered later. |
userAgent |
Sets a custom Http User-Agent to be used. This defaults to ProxerLibJava/<Version> otherwise. Pass an empty String if you don't want to sent one. |
moshi |
Sets a custom Moshi instance, used for parsing. Note, that various adapters are still applied, to make the API work properly. |
client |
Sets a custom OkHttpClient instance, used for Http requests. Note, that various interceptors are still applied, to make the API work properly. |
retrofit |
Sets a custom Retrofit instance. |
The API feature a test mode, which does not require a key. For most calls, this returns a predefined result and ignores the actual input. To enable the test mode, pass
ProxerApi.Test_KEY
or simply"test"
to the constructor.
Sending a request
The API is divided in classes for the various request, similar to the actual REST-API.
A simple query for the latest news looks like this:
List<NewsArticle> result = api.notifications()
.news()
.build()
.execute();
The build
method returns a ProxerCall
object. If you are familiar with OkHttp
, this works exactly the same. The ProxerCall
object also allows for asynchronous requests:
api.notifications().news()
.page(0)
.limit(10)
.build()
.enqueue(result -> {
// Show the result.
}, error -> {
// Show the error.
});
As you can see in the example above, the individual endpoints also allow for various options.
Coroutines
It is also possible to execute requests in a coroutine context when using Kotlin. Use the await
extension function on
the ProxerCall
:
val result = api.notifications().news().build().await()
Cancelling a request
You might want to cancel a request, especially if using on Android
:
ProxerCall call = api.[...].build()
call.cancel();
It is an error to execute a cancelled
ProxerCall
.
Error handling
All errors are encapsulated in a ProxerException
. It offers the following info about the error:
Method | Description |
---|---|
getErrorType |
Returns the general error type. |
getServerErrorType |
Returns the type of server error. |
getMessage |
Returns the associated message of the error if it was a server error. Otherwise null. |
These are the available general error types:
Type | Description |
---|---|
SERVER |
An error on the server occurred. This can for example be LOGIN_INVALID_CREDENTIALS , signaling that incorrect credentials were passed during login. |
TIMEOUT |
The server did not respond in time. |
IO |
The data transfer failed. This can happen if no network connectivity is present for example. |
PARSING |
The server sent broken data. This happens mostly when the REST-API changed and this library was not adjusted yet. |
UNKNOWN |
Any other type of error. This is an internal error in most cases. |
There is a wide range of server errors. Consult the ProxerException class for details.
Here is a selection of important ones:
Type | Description |
---|---|
INSUFFICIENT_PERMISSIONS |
Your API-key is not allowed to access the API. |
IP_BLOCKED |
You sent to many request in a specific time duration. |
*_INVALID_* |
The passed data was not correct. |
*_LOGIN_REQUIRED |
This section can only be accessed as a logged in user. |
You catch errors like this (synchronous):
try {
api.notifications().news()
.build()
.execute();
} catch (ProxerException error) {
// Handle the error here.
}
Or like this (asynchronous):
api.notifications().news()
.build()
.enqueue(result -> {
// No error occurred.
}, error -> {
// Handler the error here.
});
If you just want to present the error to the user, it can be done like so:
void handleError(ProxerException error) {
switch (error.getErrorType()) {
case SERVER:
print(error.getMessage());
break;
case TIMEOUT:
print("The server did not respond in time.");
break;
case IO:
print("Data transfer failed. Check your network connection.");
break;
case PARSING:
print("The server sent broken data.");
break;
case UNKNOWN:
print("An unkown error occurred.");
break;
}
}
Login
The ProxerApi
offers a mechanism for automatic login.
If you call the user.login
API, the relevant information is stored automatically. If you then call user.logout
, is is also removed automatically.
You can customize this behaviour through a custom LoginTokenManager
.
The most simple one looks like this (Such a LoginTokenManager
is used if you do not pass one):
ProxerApi api = new ProxerApi.Builder("yourApiKey")
.loginTokenManager(new LoginTokenManager() {
private String token;
@Nullable
@Override
public String provide() {
return token;
}
@Override
public void persist(@Nullable String loginToken) {
token = loginToken;
}
})
.build();
The token is only stored in memory with the default
LoginTokenManager
. This means, that you lose the login information when the application terminates. You may want to persist it into aFile
orSharedPreferences
onAndroid
.
Rate limiting
The api has rate limiting in place with individual limits for each api class. If more requests than the limit are performed,
a ProxerException
(with the ServerErrorType.IP_BLOCKED
) is thrown and the user has to solve a captcha. The link to the captcha page can be obtained with
ProxerUrls.captchaWeb()
.
Rate limit protection
Recent versions have a mechanism for protecting against rate limiting implemented. It can be enabled by calling the method:
ProxerApi api = new ProxerApi.Builder("yourApiKey")
.enableRateLimitProtection()
.build();
This cancels requests which would trigger the rate limit and throw a ProxerException
(with the ServerErrorType.RATE_LIMIT
).
The user does not need to solve the captcha but simply wait then.
This does not completely captcha errors. If multiple users call from the same network, the rate limit can still be hit and thus the error needs to be handled properly.
Utils
This library offers two utility classes: ProxerUrls
and ProxerUtils
.
ProxerUrls
The ProxerUrls
class has various static methods for getting often needed urls.
These are returned as an HttpUrl, which has various advantages above the default Java
classes.
Retrieving the url to the image of an user can be done like so:
HttpUrl url = ProxerUrls.userImage("image property of the UserInfo entity here");
ProxerUtils
The API often returns entities, which have enums as properties. You may want to get the String
representation, which is actually used for communication. To do so, you can use the getApiEnumName
method:
String genreAsString = ProxerUtils.getApiEnumName(Genre.ACTION);
The other way around is also available:
Genre genreAsEnum = ProxerUtils.toApiEnum(Genre.class, "Action");
ProGuard/R8
In recent versions of the library, the required config is bundled in the jar.
If you need to provide the config yourself (e.g. when using an older ProGuard version), see the config here and also look for the configs of the used libraries.
More
You can find detailed JavaDoc here.
Working on the library
Recommended development environment is IntelliJ IDEA.
Make sure to run ./gradlew build
before importing, so the IDE can pick up generated code.
Dependencies
This library is written in Kotlin and highly relies on Retrofit and OkHttp by Square for the network communication.
Moreover it uses Moshi for response parsing.
Contributions and contributors
A guide for contribution can be found here.
- @Desnoo for implementing several APIs.