Giter Site home page Giter Site logo

atm-vampirebigbird's Introduction

Development Automation with Atomist and a Reactive Spring and Kotlin-based Application

by Josh Long

Spring Framework 5, just released a few weeks ago, is the beginning of a new paradigm for the Spring ecosystem. It's a full throated embrace of the principles of reactive programming. Spring Framework 5 builds on project Reactor, extending the reactive metaphor to a new reactive web runtime and component model called Spring WebFlux. Reactive programming goes hand in hand with functional programming. Spring Framework 5 has a strong functional foundation, requiring a Java 8 baseline and shipping with Kotlin-language integrations for Spring WebFlux, bean configuration, and more.

Spring Framework 5 is only the beginning. it is the foundation for enhancements across the Spring portfolio. The just released Spring Data Kay ships with support for reactive NoSQL stores like Cassandra, Redis, Couchbase and MongoDB. We're nearing the final release of Spring Security 5.0, also built on Spring Framework 5, that supports authentication and authorization in a reactive world. All of this rolls up into Spring Boot 2.0, due in December, and Spring Cloud Finchley, due early 2018, as an integrated, reactive end-to-end experience.

In the example application, we introduce a Spring Boot 2.0.0 application, generated from the Spring Initializr. We selected the Kotlin language from the dropdown for languages, and then selected the checkboxes for Reactive Web, Reactive MongoDB, Actuator, Reactive Security. The application revolves around a MongoDB document, a Movie, which we annotate with the Spring Data annotation @Document and @Id.

@Document
data class Movie(@Id var id: String? = null, var title: String? = null)

We use a convention-based Spring Data repository - just an interface that Spring Data implements for us - to manage the data management lifecycle of the entity. The interface implies methods for reading, writing and deleting instances of the Movie entity. This is a full interface declaration. We're just extending the ReactiveMongoRepository. We don't need to provide the redundant {} definition as we would in Java.

interface MovieRepository : ReactiveMongoRepository<Movie, String>

A simple service bean defines three methods that let us read all records from the database, find a record by its ID, and generate new MovieEvent events, gated one per second, in a continuous stream .

@Service
class MovieService(private val mr: MovieRepository) {

    fun all() = mr.findAll()

    fun byId(id: String) = mr.findById(id)

    fun events(id: String) = Flux
            .generate({ sink: SynchronousSink<MovieEvent> -> sink.next(MovieEvent(id, Date())) })
            .delayElements(Duration.ofSeconds(1L))
}

We use the new service (which Spring injects as a constructor argument and that Kotlin also turns into a JavaBean property) when defining the functional reactive web endpoints. This configuration results in three HTTP endpoints, /movies, /movies/{id}, and /movies/{id}/events. The example uses the Kotlin-language specific router DSL.

@Configuration
class WebConfiguration(val ms: MovieService) {

   
    @Bean
    fun routes() = router {
        GET("/movies") { ok().body<Movie>(ms.all()) }
        
        GET("/movies/{id}") { ok().body<Movie>(ms.byId(it.pathVariable("id"))) }
        
        GET("/movies/{id}/events") {
            ok().contentType(MediaType.TEXT_EVENT_STREAM).body<MovieEvent>(ms.events(it.pathVariable("id")))
        }
    }
}

This wouldn't be much more than a toy if we didn't address security. We use Spring Security 5.0 to add in HTTP Basic authentication and authorization for two users, springrod and starbuxman. Naturally, only springrod has ADMIN authority on this system! :) Try running the application and making a curl call to the /movies endpoint with springrod's credentials: curl -uspringrod:pw http://localhost:8080/movies

@Configuration
@EnableWebFluxSecurity
class SecurityConfiguration {

    @Bean
    fun authentication() =
            MapUserDetailsRepository(
              User.withUsername("springrod").password("pw").roles("ADMIN", "USER").build(),
              User.withUsername("rob_winch").password("pw").roles("ADMIN", "USER").build(),
              User.withUsername("starbuxman").password("pw").roles("USER").build())

    @Bean
    fun authorization(http: HttpSecurity) =
            http
                    .httpBasic()
                    .and()
                    .authorizeExchange().anyExchange().hasRole("ADMIN")
                    .and()
                    .build()
}

If we're to have any hope of deploying this code into production, we'll want to support observability, too. The Spring Boot Actuator surfaces information about the service as HTTP endpoints rooted at /application. These endpoints include its /health, its HTTP /mappings, and many more. In order to enable the HTTP endpoints, we have to opt-in with a simple property in the src/main/resources/application.properties file: endpoints.default.web.enabled=true.

Running the Project

First install Mongo db if you don't have it already.

Then, start the server with:

mvn spring-boot:run

Test by visiting http://localhost:8080/movies

atm-vampirebigbird's People

Contributors

willgardella avatar

Watchers

 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.