All Downloads are FREE. Search and download functionalities are using the official Maven repository.

templates.docs.overview.html Maven / Gradle / Ivy

{#==========================================
Docs : "overview"
==========================================#}

Spincast overview

{#========================================== Section "overview / introduction" ==========================================#}

Introduction

Spincast is based on the shoulders of a giant, Guice (from Google). Other Java web frameworks may claim they support Guice, and maybe even have a section of their documentation dedicated to the topic. Spincast is one of those that is totally built on Guice, from the ground up! If you already know Guice, Spincast will be really easy to grasp for you.

Guice is not only (in our opinion) the best dependency injection library of the Java ecosystem, but also a fantastic base to build modular applications. Everything is divided into modules which are swappable and overridable. Each module can declare which dependencies it requires from other modules. In fact, Guice is so flexible that you may even find ways of using Spincast we haven't think about!

If you know another dependency injection library, like Spring, it can also help but you'll probably have to learn one of two new tricks!

Here's what using Spincast looks like at a very high level:

Users make requests to your web application. This application can have an HTML interface, built using popular tools like jQuery, React, Ember, Angular, etc. That HTML interface can be generated by Spincast (using a built-in templating engine) or can be a Single Page Application where Spincast is used as a bootstrapper and a data provider (JSON or XML) for the SPA.

Spincast is also a good platform to build REST web services or microservices, without any user interface, since it "talks" JSON and XML natively.

{#========================================== Section "architecture / architecture" ==========================================#}

Architecture

The core of a Spincast application is its Guice modules. Most of the time, your application's main Guice module will extend the default SpincastDefaultGuiceModule, so you start with a default implementation for all the required components, and not from scratch. Many components are provided by the various plugins, but your application will also bind business logic components specific to it: controllers, services, etc.

As you can see :

  • Spincast's top Guice module is SpincastCoreGuiceModule. This core module is provided by the spincast-core Maven artifact. It binds a couple of components (mostly the front controller), but its main job is to validate that implementations for all the required components have been bound by the other modules. A Spincast application is made of multiple Guice modules and each of them can validate that some required bindings have been done by other modules, or else they can throw an exception.
    The interfaces for the required components are also bundled in the spincast-core Maven artifact.
  • The other big part of Spincast is the various plugins. Plugins can provide an implementation for a required component, but can also provide extra components to add functionalities. Most of the time, a plugin has its own Guice module which you have to install to activate the plugin.
  • SpincastDefaultGuiceModule is a Guice module provided by the spincast-default Maven artifact. Its only job is to install some plugins so a default implementation is provided for all the required components. Except if you really need full control over all the implementations which are actually bound, you would probably start with that default Guice module instead of the core one. You can still tweak/override what is bound, but at least you do not start from scratch.
  • Finally, you have your application's own Guice module (here we called it AppGuiceModule). In this module, you can override some default bindings. The best example of this would be to override the implementation of the ISpincastConfig component so you can change the port the server will be running on. Of course, in this module, you're also going to bind your application specific components: the controllers, the services, etc. Since all this is standard Guice development, make sure you read Guice documentation if you have questions about the modules, the bindings and the injection of dependencies!

{#========================================== Section "architecture / request handling" ==========================================#}

Request handling

Now that we have an idea on how is structured a Spincast application, let's see how it handles requests and what are the components involved.

First, the embedded HTTP Server receives a request. This server consists of an IServer interface and an implementation. The default implementation is provided by the spincast-plugins-undertow plugin which uses the Undertow server.

If the request is for a static resource, the server serves it directly without even reaching the framework. Note that it's also possible to always generate the resource, using a standard route, so the request does enter the framework. There is even a third option which is what we call dynamic resources: if a request is made for a request which is not found, the server will pass the request to the framework. The framework can then create the resource and return it. The following requests for the same resource will use the generated resource and won't reach the framework anymore!

If the request is not for a static resource, the server passes it to the first true Spincast component: the front controller. The front controller is at the very center of Spincast! This is one of the very few components which is not provided by a plugin, but that is actually included in the spincast-core Maven artifact itself. Note that you still can extend the default front controller and override some of its methods, though, if you need to tweak one thing or two.

The job of the front controller is to:

  • Ask the router for the appropriate route to use when a request arrives.
  • Call the route handlers of the matching route. A route can have many handlers: some filters which are run before the main handler, the main handler itself, and some filters which are run after the main handler.
  • If no matching route is returned by the router, the front controller will use a Not Found route. The Not Found route can be a custom one specified by the developer, or the default one.
  • If any exception occures during any of those steps, the front controller will use an Exception route. The Exception route can be a custom one specified by the developer, or the default one.

The job of the router (interface IRouter) is to determine the appropriate route to use, given the URL of the request, its HTTP method, etc. It will also extract the value of the dynamic path tokens, if any. For example, a route path could be /user/${userId}/tasks. If a /user/42/tasks request is made, the router will extract "42" as the value of the userId parameter and make this available to the rest of the framework.

Finally, the route handlers receive a request context reprensenting the request, and decide what to return as the response. This can be anything: Json, HTML, XML or even bytes.

{#========================================== Section "architecture / Required components and their default implementations" ==========================================#}

The required components and their default implementations

The required components are those without which a Spincast application can't run. Any code, any plugin, can assume those components are available, so they can inject them and use them! Spincast's core Guice module validates that an implementation for those components is actually bound and, if not, it throws an exception.

The default implementations for those required components are bound by the SpincastDefaultGuiceModule Guice module which is provided by the spincast-default Maven artifact.

What are those required components and what are the default implementations?

  • IFrontController: this is pretty much the only component that the Spincast's core Guice module, SpincastCoreGuiceModule, binds by itself. Most of the other required components are bound by modules provided by various plugins. The default implementation is SpincastFrontController. In general, you don't have to use this component directly.
  • IServer: the embedded HTTP server. The default implementation, SpincastUndertowServer , uses the Undertow server and is provided by the Spincast Undertow plugin.
  • IRouter: the router. The default implementation is SpincastRouter. There is also a IDefaultRouter interface which extends IRouter and parametrizes it with the default request context type, IDefaultRequestContext. All those implementations are provided by the Spincast Routing plugin.
  • ITemplatingEngine: the templating engine to generate HTML and other text containing placeholders. The default implementation, SpincastPebbleTemplatingEngine, uses Pebble and is provided by the Spincast Pebble plugin.
  • IJsonManager: to read and write Json content. The default implementation, SpincastJsonManager, uses Jackson as the Json library and is provided by the Spincast Jackson Json plugin.
  • IXmlManager: to read and write XML content. The default implementation, SpincastXmlManager, uses Jackson as the XML library and is provided by the Spincast Jackson XML plugin.
  • ISpincastConfig: provides configurations required by Spincast, for example the port on which the server should start. The default implementation, SpincastConfig simply hardcodes default values and is provided by the Spincast Config plugin.
  • ISpincastDictionary: provides some labels Spincast requires, for example the message to display publicly if the default Not Found route is used. The default implementation, SpincastDictionary simply hardcodes english values and is provided by the Spincast Dictionary plugin.
  • ICookieFactory and ICookie: used to create cookies. The implementations and binding are provided by the Spincast Cookies plugin.

{#========================================== Section "architecture / Transitive dependencies" ==========================================#}

Transitive dependencies

The spincast-core Maven artifact only has 3 direct dependencies which are external to Spincast:

  • com.google.inject:* (Guice), which pulls three transitive dependencies :
    • com.google.guava:guava-parent (Guava)
    • javax.inject:javax.inject
    • aopalliance:aopalliance
  • com.google.code.findbugs:jsr305 : For the @Nullable annotation.
  • org.slf4j:slf4j-api : The SLF4J logging facade.

The versions used for those dependencies are defined in the spincast-parent Maven artifact's pom.xml.

Spincast core also uses some Apache commons libraries, but those are shaded, their classes have been relocated under Spincast's org.spincast.shaded package, so they won't conflit with your own dependencies.

That said, each plugin also adds some more dependencies! If you start with the spincast-default Maven artifact, a bunch of transitive dependencies will be included. If you need full control over the transitives dependencies added to your application, start with the spincast-core Maven artifact and pick, one by one, the plugins and implementations you want to use.





© 2015 - 2025 Weber Informatics LLC | Privacy Policy