templates.docs.overview.html Maven / Gradle / Ivy
Show all versions of spincast-website Show documentation
{#==========================================
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 from a user. 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.
                     
                    - 
                        It's a little bit different if the request is for a 
WebSocket connection. In that
                        case, the handling of the request is made by a WebSocket controller instead of a route handler.
                        Also, the result is not a simple response but a permanent and full duplex connection where each side 
                        can send messages to the other side.
                        Have a look at the WebSockets section for more information!
                     
                    - 
                        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.
                        
                        or:
                     
                    - 
                        A 
WebSocket controller receives the request for a WebSocket connection, allows or
                        denies it, and then receives and sends messages on that connection.
                     
                
            
        
    
    
    {#==========================================
    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/WebSocket 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 parameterizes it with
                    some default types, IDefaultRequestContext and IDefaultWebsocketContext. 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.