Giter Club home page Giter Club logo

snoozy's Introduction

Snoozy

Build Status

Snoozy allows building JAX-RS applications without depending on the specific app-server or Servlet container implementation.

Servers

Current server selection consists of:

  • Undertow

Application

Application is an extended version of javax.ws.rs.core.Application providing additional feature declarations, such as static files. The additional features are defined using a declarative api keeping things implementation agnostic.

Example of Application class

public class App extends Application {
    @Override
    public Set<Object> getClasses() {
        return Stream.of(
                // Place your filter, provider and resource classes here
        ).collect(Collectors.toSet());
    }

    @Override
    public Set<Object> getSingletons() {
        return Stream.of(
                // Place your filters, providers and resources here
        ).collect(Collectors.toSet());
    }

    @Override
    public Set<StaticFiles> getStaticFiles() {
        return Stream.of(
                // Place your StaticFiles objects here
        ).collect(Collectors.toSet());
    }

    public static void main(String[] args) {
        new UndertowServer().start(new App());
    }
}

AuthenticatedApplication<P extends UserPrincipal>

AuthenticatedApplication is an extended version of our Application implementation that provides additional feature declarations for authentication

Example of AuthenticatedApplication

public class App extends AuthenticatedApplication<User> {
    @Override
    public Set<Object> getClasses() {
        return Stream.of(
                // Place your filter, provider and resource classes here
        ).collect(Collectors.toSet());
    }

    @Override
    public Set<Object> getSingletons() {
        return Stream.of(
                // Place your filters, providers and resources here
        ).collect(Collectors.toSet());
    }

    @Override
    public Set<StaticFiles> getStaticFiles() {
        return Stream.of(
                // Place your StaticFiles objects here
        ).collect(Collectors.toSet());
    }

    @Override
    public Authentication<User> getAuthentication() {
        return Authentication.<User>builder()
                .setAuthenticator(new StatefulAuthenticator<>())
                .setAuthorizer(new DefaultAuthorizer<>())
                .setTokenParser(HeaderParser.of("Authorization"))
                .setUserClass(User.class)
                .build();
    }

    public static void main(String[] args) {
        new UndertowServer().start(new App());
    }
}

StaticFiles

StaticFiles are used to define URL paths, resource paths and access levels of static files.

Notes:

  • By default, methodAccess is set to authenticated.
  • path is the relative URL path
  • prefix is the relative resource path
  • rewrite allows you to define a regex rule to rewrite matching paths. For example, define rules to return index.html on other paths than just / and /index.html to support client-side routing.

Example of a StaticFiles declaration

@Override
public Set<StaticFiles> getStaticFiles() {
    // Files will be served from the folder "public" under "resources" to
    // everybody
    StaticFiles files = StaticFiles.builder()
            .setPrefix("public")
            .setClassLoader(this.getClass().getClassLoader())
            .setMethodAccess(MethodAccess.anonymous())
            .setRewrite(
                UrlRewrite.build()
                    // Everything except paths starting with /api or /assets and
                    // paths ending with .html or .png will be rewrited to
                    // /index.html
                    .setFrom("^\/(?!(((api|assets).*)|.*\.(html|png)$)).*$")
                    .setTo("/index.html")
                    .build()
            )
            .build();

    return Stream.of(files)
            .collect(Collectors.toSet());
}

Authentication<P extends UserPrincipal>

Authentication is used to define the behaviour of the authenticator.

Notes:

  • If available, a User Principal is injected into context and can be accessed in resources via the JAX-RS @Context annotation. e.g @Context User user

Properties:

  • Authenticator handles the actual authentication. It takes a token and if valid, returns the corresponding user. A simple in-memory stateful authenticator is provided.
  • Authorizer checks that the user has the correct role and return true or false. This can be used to defined tiered access level where an admin can access all resources that a user can, but a user cannot access everything that an admin can. A simple string comparison authorizer is provided.
  • TokenParser takes the actual request and if valid, returns a token. Simple header and cookie parsers are provided.
  • UserClass is a class extending the UserPrincipal class. It must contain at least a name and role, but additional metadata may be kept.

Example of Authentication

@Override
public Authentication<User> getAuthentication() {
    return Authentication.<User>builder()
            .setAuthenticator(new StatefulAuthenticator<>())
            .setAuthorizer(new DefaultAuthorizer<>())
            .setTokenParser(HeaderParser.of("Authorization"))
            .setUserClass(User.class)
            .build();
}

Additional Resources

Dependency Injection

Our choice of DI framework is Dagger 2. Here is a small getting started guide on how to use Dagger 2 with Snoozy.

  • Add the following to your pom.xml dependencies
<dependency>
    <groupId>com.google.dagger</groupId>
    <artifactId>dagger</artifactId>
    <version>2.21</version>
</dependency>
<dependency>
    <groupId>com.google.dagger</groupId>
    <artifactId>dagger-compiler</artifactId>
    <version>2.21</version>
    <scope>provided</scope>
</dependency>
  • Create a Dagger Component which at the very least has a method that will provide your Application object.
import dagger.Component;

import javax.inject.Singleton;

@Singleton
@Component
public interface ApplicationComponent {
    Application getApplication();
}
  • Instead of instantiating an Application object yourself in your main method, let Dagger do the work for you.
Application application = DaggerApplication.create()
        .getApplication();

NOTE: If you have not ran mvn package after the previous step, your IDE might complain about DaggerApplication. This class is generated during compile time and will be present in the maven target folder.

  • In some cases you might want Dagger to instantiate an object that it does not know how to. For example, your configuration object or and interface. In these cases you will have to create a Dagger module which provides a factory method:
import dagger.Module;
import dagger.Provides;
import fi.jubic.easyconfig.ConfigMapper;
import fi.jubic.easyconfig.MappingException;

import javax.inject.Singleton;

@Module
class ApplicationModule {
    @Provides
    @Singleton
    static Configuration provideConfiguration() {
        try {
            return new ConfigMapper().read(Configuration.class);
        } catch (MappingException e) {}

        return null;
    }
}

You will also have to register this Module in the Component we previously created.

import dagger.Component;

import javax.inject.Singleton;

@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
    Application getApplication();
}

NOTE: If you want Dagger to instantiate an object of your own which has no dependencies. You can just add @Inject to a constructor with no parameters.

snoozy's People

Contributors

vilppuvuorinen avatar aleksigold avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.