-
Notifications
You must be signed in to change notification settings - Fork 140
[Rough Cut] Delivering up Single Page Applications from QBit Java JSON Microservice lib
QBit can server up non-JSON resources. The QBit lib allows you to bind objects to HTTP ports so that they can be called by REST and WebSocket clients.
/* The service. */
@RequestMapping("/todo-manager")
public class TodoService {
private final TodoRepository todoRepository = new ListTodoRepository();
@RequestMapping("/todo/size")
public int size() {
return todoRepository.size();
}
@RequestMapping("/todo/list")
public List<TodoItem> list() {
return todoRepository.list();
}
...
/* Then to start up. */
public class TodoServerMain {
public static void main(String... args) {
ServiceEndpointServer
ServiceEndpointServer
ServiceEndpointServer server = new EndpointServerBuilder().setRequestBatchSize(100).build();
server.initServices(new TodoService());
server.start();
}
}
This is a smaller version of the wiring that starts things up and registers a system manager. And waits for the server to shutdown.
QBitSystemManager systemManager = new QBitSystemManager();
ServiceEndpointServer
ServiceEndpointServer
ServiceEndpointServer server = endpointServerBuilder()
.setSystemManager(systemManager).build()
.initServices(new TodoService()).startServer();
systemManager.waitForShutdown();
Now let's see, how do we use a ServiceEndpointServer ServiceEndpointServer ServiceEndpointServer to host our REST and WebSocket and still deliver up a single page app.
Ok.. let's walk you through another example....
This is a simple HelloWorld type of an example.
Here is our HTML page. Small and to the point. Just example ware ok.
<!DOCTYPE html>
<html>
<body>
<p>click the button:</p>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
<script>
function httpGet(theUrl)
{
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false );
xmlHttp.send( null );
return xmlHttp.responseText;
}
function myFunction() {
var json = httpGet("/services/helloservice/hello");
var helloObject = JSON.parse(json);
document.getElementById("demo").innerHTML = helloObject.hello;
}
</script>
</body>
</html>
The above page sends request (REST/HTTP/GET), and gets back some JSON which is parses and displays the hello property. It is simple and small on purpose.
To deliver up this page, instead of having the EndpointServerBuilder create an HttpServer, we will create one for it, and pass that to the builder. HttpServer uses Java 8 functional interfaces to register event handlers for WebSocket events and HttpRequest events. The special sauce in Java 8 is called a Consumer. The HttpServer also uses a special sauce Java 8 sauce Predicate. With the Predicate callback, you can specify if you want the request to be handled by the consumer or not. This means all we have to do is create a Predicate that handles the request and then return false so the consumer which is wired into the EndpointServerBuilder is never called. Then we load the resource "/ui/helloWorld.html". And we deliver that up. All other requests we let go through.
Let's show the code. First the HelloWorld object.
public class HelloObject {
private final String hello;
private final long time = System.currentTimeMillis();
public HelloObject(String hello) {
this.hello = hello;
}
}
That is your M in the MVC world. (M Model) :)
Next the C in the MVC world. (C controller)
@RequestMapping("/helloservice")
public class HelloService {
@RequestMapping("/hello")
public HelloObject hello() {
return new HelloObject("Hello World!");
}
}
Now we need to deliver up the V. (View).
When you run this one, you can see it here.
http://localhost:9999/ui/helloWorld.html
public class HelloWorldRestServer {
public static final String HTML_HELLO_PAGE = "/ui/helloWorld.html";
public static void main(String... args) {
/* Create the system manager to manage the shutdown. */
QBitSystemManager systemManager = new QBitSystemManager();
HttpServer httpServer = httpServerBuilder()
.setPort(9999).build();
/* Register the Predicate using a Java 8 lambda expression. */
httpServer.setShouldContinueHttpRequest(httpRequest -> {
/* If not the page uri we want to then just continue by returning true. */
if ( ! httpRequest.getUri().equals(HTML_HELLO_PAGE) ) {
return true;
}
/* read the page from the file system or classpath. */
final String helloWorldWebPage = resource(HTML_HELLO_PAGE);
/* Send the HTML file out to the browser. */
httpRequest.getResponse().response(200, "text/html", helloWorldWebPage);
return false;
});
/* Start the service. */
final ServiceEndpointServer
ServiceEndpointServer
ServiceEndpointServer serviceServer = endpointServerBuilder().setSystemManager(systemManager)
.setHttpServer(httpServer).build().initServices(new HelloService()).startServer();
/* Wait for the service to shutdown. */
systemManager.waitForShutdown();
}
}
You can find the full example here:
Hello World Full Example Showing Single Page App With QBit Microservice lib
QBit Website What is Microservices Architecture?
QBit Java Micorservices lib tutorials
The Java microservice lib. QBit is a reactive programming lib for building microservices - JSON, HTTP, WebSocket, and REST. QBit uses reactive programming to build elastic REST, and WebSockets based cloud friendly, web services. SOA evolved for mobile and cloud. ServiceDiscovery, Health, reactive StatService, events, Java idiomatic reactive programming for Microservices.
Reactive Programming, Java Microservices, Rick Hightower
Java Microservices Architecture
[Microservice Service Discovery with Consul] (http://www.mammatustech.com/Microservice-Service-Discovery-with-Consul)
Microservices Service Discovery Tutorial with Consul
[Reactive Microservices] (http://www.mammatustech.com/reactive-microservices)
[High Speed Microservices] (http://www.mammatustech.com/high-speed-microservices)
Reactive Microservices Tutorial, using the Reactor
QBit is mentioned in the Restlet blog
All code is written using JetBrains Idea - the best IDE ever!
Kafka training, Kafka consulting, Cassandra training, Cassandra consulting, Spark training, Spark consulting
Tutorials
- QBit tutorials
- Microservices Intro
- Microservice KPI Monitoring
- Microservice Batteries Included
- RESTful APIs
- QBit and Reakt Promises
- Resourceful REST
- Microservices Reactor
- Working with JSON maps and lists
__
Docs
Getting Started
- First REST Microservice
- REST Microservice Part 2
- ServiceQueue
- ServiceBundle
- ServiceEndpointServer
- REST with URI Params
- Simple Single Page App
Basics
- What is QBit?
- Detailed Overview of QBit
- High level overview
- Low-level HTTP and WebSocket
- Low level WebSocket
- HttpClient
- HTTP Request filter
- HTTP Proxy
- Queues and flushing
- Local Proxies
- ServiceQueue remote and local
- ManagedServiceBuilder, consul, StatsD, Swagger support
- Working with Service Pools
- Callback Builders
- Error Handling
- Health System
- Stats System
- Reactor callback coordination
- Early Service Examples
Concepts
REST
Callbacks and Reactor
Event Bus
Advanced
Integration
- Using QBit in Vert.x
- Reactor-Integrating with Cassandra
- Using QBit with Spring Boot
- SolrJ and service pools
- Swagger support
- MDC Support
- Reactive Streams
- Mesos, Docker, Heroku
- DNS SRV
QBit case studies
QBit 2 Roadmap
-- Related Projects
- QBit Reactive Microservices
- Reakt Reactive Java
- Reakt Guava Bridge
- QBit Extensions
- Reactive Microservices
Kafka training, Kafka consulting, Cassandra training, Cassandra consulting, Spark training, Spark consulting