Reactive library for command-based architecture creating. It can be used for both Android and Java.
- Flexibility and scalability. Scale functionality using services
- Reactive approach for any actions manipulating with a help of RXJava
- Throw-safety architecture.
Janet helps to write clear maintainable code because each individual operation is an individual class where this operation is described. Let's call it as Action.
But Janet doesn't perform actions. For that Janet uses services that has algorithm of action processing. Each action is linked to service using an annotation that is defined in the method ActionService.getSupportedAnnotationType()
. Janet is like action router that can send and receive actions using added services. And service knows what to do with the action.
To use any service add it to the Builder using method addService
Janet janet = new Janet.Builder()
.addService(new HttpActionService(API_URL, new OkClient(), new GsonConverter(new Gson())))
At this moment there are 3 services in Janet:
- HttpActionService to provide HTTP/HTTPS requests execution
- AsyncActionService to provide support async protocols like socket.io
- CommandActionService to invoke custom logic as command
Also there is an ability to add custom service if needed
After Janet's instance creation all works with action are performed using ActionPipe
End tool for sending and receiving actions with specific type using RXJava. ActionPipe works with actions asynchronously. Create instances using method Janet.createPipe
.
For example,
ActionPipe<UsersAction> usersPipe = janet.createPipe(UsersAction.class);
usersPipe.observeSuccess()
.subscribe();
usersPipe.createObservable(new UsersAction())
.subscribe();
usersPipe.send(new UsersAction());
Each HTTP request for HttpActionService is an individual class that contains all information about the request and response.
Http action must be annotated with @HttpAction
@HttpAction(value = "/demo", method = HttpAction.Method.GET)
public class ExampleAction {}
To configure request, Action fields can be annotated with:
@Path
for path value@Query
for request URL parameters@Body
for POST request body@RequestHeader
for request headers@Field
for request fields if request type isHttpAction.Type.FORM_URL_ENCODED
@Part
for multipart request parts
To process response, special annotations can be used:
@Response
for getting response body.@Status
for getting response status. Field typesInteger
,Long
,int
orlong
can be used to get status code or useboolean
to know that request was sent successfully@ResponseHeader
for getting response headers
@HttpAction(value = "/demo/{examplePath}/info",
type = HttpAction.Type.SIMPLE,
method = HttpAction.Method.GET)
public class ExampleAction {
@Path("examplePath")
String ownerr;
@Query("repo")
int query;
@RequestHeader("Example-Header-Name")
String requestHeaderValue;
@Status
int statusCode;
@Body
ExampleModel exampleModel;
@Response
ExampleDataModel exampleDataModel;
@ResponseHeader("Example-Responseheader-Name")
String responseHeaderValue;
}
AsyncActionService performs actions with annotation @AsyncAction. Every action is async message that contains message data as a field annotated with @AsyncMessage.
Also AsyncActionService has algorithm to synchronize outcoming and incoming messages. To receive action response may add field with annotation @SyncedResponse. Type of that field must be a class of incoming action. To link action with its response set class in the annotation implemented by SyncPredicate where the condition for synchronization present.
@AsyncAction(value = "test", incoming = true)
public class TestAction {
@AsyncMessage
Body body;
@SyncedResponse(value = TestSyncPredicate.class, timeout = 3000)
TestAction response;
@Override public String toString() {
return "TestAction{" +
"body=" + body +
", response=" + response +
'}';
}
public static class TestSyncPredicate implements SyncPredicate<TestAction, TestAction> {
@Override public boolean isResponse(TestAction requestAction, TestAction response) {
return requestAction.body.id == response.body.id;
}
}
}
CommandActionService performs actions executing with a help of annotation @CommandAction. Also to create command action it's necessary to implement the interface CommandActionBase. It contains the command's methods for running and cancellation. To get command result use method getResult()
@CommandAction
public class ExampleCommandAction extends CommandActionBase<String> {
@Override protected String run(CommandCallback callback) throws Throwable {
//perform logic to return result
}
@Override public void cancel() {
//cancellation if needed
}
}
Grab via Maven
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.techery.janet</groupId>
<artifactId>janet</artifactId>
<version>0.0.11</version>
</dependency>
or Gradle:
repositories {
...
maven { url "https://jitpack.io" }
}
dependencies {
compile 'com.github.techery.janet:janet:0.0.11'
}
List of additional artifacts:
compile 'com.github.techery.janet:http-service:0.0.11'
apt 'com.github.techery.janet:http-service-compiler:0.0.11'
compile 'com.github.techery.janet:okhttp:0.0.11'
compile 'com.github.techery.janet:okhttp3:0.0.11'
compile 'com.github.techery.janet:android-apache-client:0.0.11'
compile 'com.github.techery.janet:url-connection:0.0.11'
compile 'com.github.techery.janet:async-service:0.0.11'
apt 'com.github.techery.janet:async-service-compiler:0.0.11'
compile 'com.github.techery.janet:nkzawa-socket.io:0.0.11'
compile 'com.github.techery.janet:socket.io:0.0.11'
compile 'com.github.techery.janet:gson:0.0.11'
compile 'com.github.techery.janet:protobuf:0.0.11'
compile 'com.github.techery.janet:command-service:0.0.11'