Spring Framework

Spring Framework Stereotypes

  • Stereotype - a fixed general image or ser of characteristics which represent a particular type of person or thing
  • Spring Stereotypes are class level annotations used to define Spring Beans
    • when classes annotated with Spring Stereotypes are detected via the component scan, an instance of the class will be added to the Spring context
  • Available Spring Stereotypes
    • @Component
    • @Controller
    • @RestController
    • @Repository
    • @Service
Annotation Description
@Component Indicates that an annotated class is a component and it will be created as a bean
@Controller indicates that an annotated class has the role of a Spring MVC controller
@RestController convenience annotation which extends @Controller and @ResponseBody
@Repository indicates class is a Repository, a mechanism for encapsulating storage, retrieval, and search behavior which emulates a collection of objects
@Service indicates that an annotated class is a Service, an operation offered as an interface that stands alone in the model, with no encapsulated state

Spring Component Scan

  • Spring Beans defined with Spring Stereotypes are detected with Spring component scan
  • On startup, Spring is told to scan packages for classes with Spring Stereotype annotations
  • This configuration is Spring Framework specific, not Spring Boot
  • Spring Boot’s auto configuration will tell Spring to perform a component scan of the package of the main class
    • this includes all sub packages of the main class package
  • when using Spring Boot, if class is outside of the main class package tree, you must declare the package scan manually

Spring Bean Scopes

  • Singleton - (default) only one instance of the bean is created in the IoC container
  • Prototype - A new instance is created each time the bean is requested
  • Request - For web app, a single instance per http request, only valid in the context of a web aware Spring applicationContext
  • Session - for web app, a single instance per http session, only valid in the context of a web aware Spring applicationContext
  • Global-session - a single instance per global session, typically only used in a Portlet context, only valid in the context of a web aware Spring applicationContext
  • Application - bean is scoped to the lifecycle of a ServletContext, only valid in the context of web aware
  • WebSocket - scopes a single bean definition to the lifecycle of a WebSocket, only valid in the context of a web aware Spring applicationContext
  • Custom Scope - Spring Scopes are extensible, and you can define your own scope by implementing Spring’s scope interface

Declaring Bean Scope

  • No declaration needed for singleton scope
  • in Java configuration use @Scope annotation
  • in XML configuration file scope is an XML attribute of the bean tag
  • 99% of the time singleton scope is fine

External Properties

  • Why use External Properties?
    • hard coding values which can change is considered a bad practice
    • makes your application rigid and hard to change
    • you want your application to be portable
      • deployment artifact (jar, war) should be deployable to different environments
  • what can change?
    • usernames, passwords, urls, API keys, paths, queue names etc…

which property files to use

  • using application.properties or application.yml in packaged JAR or WAR
  • using profile specific properties or YAML files for profile specific properties
  • for deployments, override properties that change with environment variables
    • typically 70 - 80% of values do not change, only override what is needed
    • environment variables offer a secure way of seeing sensitive values such as passwords

Properties Setting Hierarchy (from low to high)

  1. application.properties
  2. environment variables
  3. command line variables

Thymeleaf

  • Thymeleaf is a Java template engine producing XML, XHTML and HTML5
  • Thymeleaf is a replacement of JSPs
  • Thymeleaf is a natural template engine (the templates are viewable in a web browser)
  • is not tied to web environment (can be used for producing HTML for emails)
  • Thymeleaf is not a web framework

Request Methods

  • GET
    • is a request for a resource (html file, javascript file, image, etc…)
    • is used when you visit a website
  • HEAD
    • is like GET, but only asks for meta information without the body
  • POST
    • is used to post data to the server
    • typical use case for POST is to post form data to the server (like a checkout form)
    • POST is a create request
  • PUT
    • is a request for the enclosed entity be stored at the supplied URI, if the entity exists, it is expected to be updated
    • PUT is a create OR update request
  • DELETE
    • is a request to delete the specified resource
  • TRACE
    • will echo the received request, can be used to see if request was altered by intermediate servers
  • OPTIONS
    • returns the HTTP methods supported by the server for the specified URL

Safe methods

  • safe methods are considered safe to use because they only fetch information and do not cause changes on the server
  • the safe methods are: GET, HEAD, OPTIONS, and TRACE

Idempotent methods

  • a quality of an action such that repetitions of the action have no further effect on the outcome
  • PUT and DELETE are Idempotent methods
  • safe methods (GET, HEAD, OPTIONS and TRACE) are also Idempotent
  • being truly idempotent is not enforced by the protocol

Non-Idempotent methods

  • POST is NOT idempotent
  • multiple POSTs are likely to create multiple resources
  • Ever seen websites asking you to click submit only once?

HTTP Status Codes

  • 100 series are information in nature
  • 200 series indicate successful request
    • 200 Okay, 201 Created, 204 Accepted
  • 300 series are redirections
    • 301 Moved Permanently
  • 400 series are client errors
    • 400 Bad Request, 401 Not Authorized, 404 Not Found
  • 500 series are server side errors
    • 500 Internel Server Error, 503 Service Unavailable

Developer Tools

  • added to project via artifact ‘spring-boot-devtools’
  • developer tools are automatically disabled when running a packaged application
  • by default, not included in repackaged archives

Features

  • by default you need to select Build -> Make project
  • there is an advanced setting you can change to make this more seamless

Template caching

  • by default templates are cached for performance
  • but caching will require a container restart to refresh the cache
  • developer tools will disable template caching so the restart is not required to see changes

LiveReload

  • LiveReload is a technology to automatically trigger a browser refresh when resources are changed
  • Spring boot developer tools includes a LiveReload server

Entity Relationships

  • One to One
    • One entity is related to one other entity
  • One to Many
    • One entity is related to many entities (List, Set, Map, SortedSet, SortedMap)
  • Many to One
    • the inverse relationship of one to many
  • Many to Many
    • many entities are related to many entities
    • each has a list or set reference to the other
    • a join table us used to define the relationships (mapping table)

Unidirectional vs Bidirectional

  • Unidirectional is one way
    • mapping is only done one way, one side of the relationship will not know about the other
  • Bidirectional is two way
    • both sides know about each other
    • generally recommended to use bidirectional, since you can navigate the object graph in either direction

Owning side

  • the Owning side in the relationship will hold the foreign key in the database
  • one to one is the side where the foreign key is specified
  • one to many and many to one is the Many side
  • mappedBy is used to define the field with owns the reference of the relationship

Fetch type

  • Lazy - data is not required until referenced
  • Eager - data is queried up front

JPA Cascade Types

  • JPA Cascade types control how state changes are cascaded from parent objects to child objects
  • Types
    • PERSIS
    • MERGE
    • REFRESH
    • REMOVE
    • DETACH
    • ALL
  • by default, no operations are cascaded

Embeddable Types

  • JPA / Hibernate support embeddable types
  • these are used to define a common set of properties
  • for example, an order might have a billing address and a shipping address
  • an embeddable type could be used for the address properties for reuse

Inheritance

  • mappedSuperclass - entities inherit from a super class, a database table IS NOT created for the super class
  • Single Table - default - one table is used for all subclasses
  • Joined Table - base class and subclasses have their own tables, fetching subclass entities require a join to the parent table (subclasses will not have the common properties from the parent class)
  • Table Per Class - each subclass has its own table (no table for parent class. common properties will exist in all subclasses)

Create and Update Timestamps

  • often a best practice to use create and update timestamps on your entities for audit purposes
  • JPA supports @PrePersist and @PreUpdate which can be used for support audit timestamps via JPA lifecycle callbacks
  • hibernate provides @CreationTimestamp and @UpdateTimestamp

Hibernate DDL Auto

  • DDL - Data Definition Language
  • DML - Data Manipulation Language
  • Hibernate property is set by the Spring property
  • options are
    • none
    • validate - check if there is any table or columns that are missing
    • update - find missing table and columns and update the existing DB, not good for PROD environment
    • create - create the DB
    • create-drop - create the DB and drop the DB when application instance stops running.
  • Spring boot will use create-drop for embedded databases (HSQL, H2, Derby) or none

DDL vs DML

  • DDL is used to define database structures such as tables and indexes, while DML is used with data operations such as inserts and updates

Initialize with Hibernate

  • data can be loaded from import.sql, this is a file that can be created in the root path
  • Hibernate feature, not Spring specific
  • must be on root of class path
  • only executed if Hinernate’s DDL auto property is set to create or create-drop

Spring JDBC

  • Spring’s datasource initializer via Spring Boot will by default load schema.sql and data.sql from the root of the class path
  • Spring Boot will also load from schema-${platform}.sql and data-${platform}.sql
  • must set spring.datasource.platform property
  • may conflict with Hinernate DDL auto property
    • if using Spring datasource initializer, should set DDL auto property to none or validate

Spring Data JPA Query Method

  • define method in interface
  • method name rules: findBy + <PROPERTY_NAME>
  • it will create the query based on method name and query the database to find the data and return to us.
  • no manual implementation needed.

Repository layer and Service layer

  • All your business logic should be in the Service Layer.
  • Any access to the Database (any storage) should go to the Repository Layer.
  • Lets take an Example. You have to save an entity(Person). But before saving the Person you want to make sure that the Person’s FirstName does not exist already.
    So the validation part should go to the business layer.
    In the service Layer
1
2
3
4
5
6
7
8
9
10
11
12
PersonRepository repository; 
public Person save(Person p){
Person p = findByName(p.getName();
if (p != null){
return some customException();
}
return repository.save(p);
}

public Person findByName(String name){
return repository.findByName(name);
}
  • And in your Repository Layer just concentrate on DB Operation.

  • View<-->Controller( create instance of Model class)<-->Service<--->Repository

Lombok

  • hooks in via the annotation processor API
  • the raw source code is passed to Lombok for code generation before the Java complier continues
  • thus, produces properly compiled Java code in conjunction with the Java compiler
  • under the classes you can view the compiled class files
  • IntelliJ will decompile to show you the source code

IDEs

  • since compiled code is change, and source files are not, IDE’s can get confused by this
  • more of an issue for IDEs several years old
  • modern IDEs such as IntelliJ, Eclipse support Project Lombok
  • Plug in Installation may be necessary
  • IntelliJ
    • verify you have enabled annotation processing under compiler settings

features

  • val - local variables declared final
  • var - mutable local variables
  • @NonNull - Null check, will throw NPE if parameter is null
  • @Cleanup - will call close() on resource/connection in finally block
  • @Getter - creates getter methods for all properties
  • @Setter - creates setter for all non-final properties
  • @ToString
    • generates String of classname, and each field separated by commas
    • optional parameter to include field names
    • optional parameter to include call to the super toString method
  • @EqualsAndHashCode
    • generates implementations of equals(Object other) and hashCode()
    • by default will use all non-static, non-transient properties
    • can optionally exclude specific properties
  • @NoArgsConstructor
    • generates no args constructor
    • will cause compiler error if there are final fields
    • can optionally force, which will initialize final fields with 0 / false / null
  • @RequiredArgsConstructor
    • generates a constructor for all fields that are final or marked @NonNull
    • constructor will throw a NullPointerException if any @NonNull fields are null
  • @AllArgsConstructor
    • generates a constructor for all properties of class
    • any @NotNull properties will have null check
  • @Data
    • generates typical boilerplate code for POJOs
    • combines - @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor
    • no constructor is generated if constructors have been explicitly declared
  • @Value
    • the immutable variant of @Data
    • all fields are made private and final by default
  • @NonNull
    • set on parameter of method or constructor and a NullPointerException will be thrown if parameter is null
  • @Builder
    • implements the builder pattern for object creation
  • @SneakyThrows
    • throw checked exceptions without declaring in calling method’s throws clause
  • @Synchronized
    • a safer implementation of Java’s synchronized
  • @Getter(lazy = true)
    • for expensive getters
    • will calculate value first time and cache
    • additional gets will read from cache
  • @Log
    • creates a Java util logger
  • @Slf4j
    • creates a SLF4J logger
    • recommended - SLF4J is a generic logging facade
    • spring boot’s default logger is LogBack

Testing Terminology

  • Code under test
    • this is the code you are testing
  • Test fixture
    • a test fixture is a fixed state of a set of objects used as a baseline for running tests. The purpose of a test fixture is to ensure that there is a well known and fixed environment in which tests are run so that results are repeatable
    • includes: input data, mock objects, loading database with known data etc…

Unit Tests

  • code written to test code under test
  • designed to test specific sections of code
  • percentage of lines of code tested is code coverage
    • ideal coverage is in the 70-80% range
  • should be unity and execute very fast
  • should have no external dependencies
    • no databases, no Spring Context etc…

Integration tests

  • designed to test behaviors between objects and parts of the overall system
  • much larger scope
  • can include Spring Context, database, and message brokers
  • will run much slower than unit tests

Functional tests

  • typically means you are testing the running application
  • application is live, likely deployed in a known environment
  • functional touch points are tested
  • i.e. using a web driver, calling web services, sending / receiving messages etc…(Selenium)

TDD

  • test driven development
  • write tests first, which will fail, then code to fix the tests

BDD

  • behavior driven development
  • builds on TDD and specifies that tests of any unit of software should be specified in terms of desired behavior of the unit
    • often implemented with DSLs to create natural language tests
    • JBehave, Cucumber, Spock

Mock

  • a fake implementation of a class used for testing, like a test double

Spy

  • a partial mock, allowing you to override select methods of a real class

Testing goals

  • generally, you will want the majority of your tests to be unit tests
  • bringing up the Spring Context makes your tests exponentially slower
  • try to test specific business logic in unit tests
  • use Integration tests to test interactions
  • think of a pyramid, base is unit tests, middle is integration tests, top is functional tests

Test scope dependencies

  • using spring-boot-starter-test
    • JUnit - the default standard for unit testing Java applications
    • Spring test and Spring boot Test - utilities and integration test support for Spring Boot applications
    • AssertJ - a fluent assertion library
    • Hamcrest - a library of matcher objects
    • Mockito - a Java mocking framework
    • JSONassert - an assertion library for JSON
    • JSONPath - XPath for JSON

JUnit Annotations

Annotation Description
@Test identifies a method as a test method
@Before executed before each test, it is used to prepare the test environment (e.g. read input data, initialize the class)
@After executed after each test, it is used to cleanup the test environment, it can also save memory by cleaning up expensive memory structures
@BeforeClass executed once, before the start of all tests, methods marked with this annotation need to be defined as static to work with JUnit
@AfterClass executed once, after all tests have been finished, methods annotated with this annotation need to be defined as static to work with JUnit
@Ignore marks that the test should be ignored
@Test(expected = Exception.class) fails if the method does not throw the named exception
@Test(timeout = 10) fails if the method takes longer than 100 milliseconds

Spring Boot Annotations

Annotation Description
@RunWith(SpringRunner.class) run test with Spring Context
@SpringBootTest search for Spring boot application for configuration
@TestConfiguration specify a Spring configuration for you test
@MockBean injects Mockito mock
@SpyBean injects Mockito Spy
@JsonTest creates a Jackson or Gson object mapper via Spring boot
@WebMvcTest used to test web context without a full http server
@DataJpaTest used to test data layer with embedded database

ArgumentCaptor

  • ArgumentCaptor allows us to capture an argument passed to a method in order to inspect it. This is especially useful when we can’t access the argument outside of the method we’d like to test.
  • For example, consider an EmailService class with a send method that we’d like to test:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class EmailService {

private DeliveryPlatform platform;

public EmailService(DeliveryPlatform platform) {
this.platform = platform;
}

public void send(String to, String subject, String body, boolean html) {
Format format = Format.TEXT_ONLY;
if (html) {
format = Format.HTML;
}
Email email = new Email(to, subject, body);
email.setFormat(format);
platform.deliver(email);
}

...
}
  • In EmailService.send, notice how platform.deliver takes a new Email as an argument. As part of our test, we’d like to check that the format field of the new Email is set to Format.HTML. In order to do this, we need to capture and inspect the argument that is passed to platform.deliver.

Set up the unit test

  • First, let’s create our unit test class:
1
2
3
4
5
6
7
8
9
10
11
RunWith(MockitoJUnitRunner.class)
public class EmailServiceUnitTest {

@Mock
DeliveryPlatform platform;

@InjectMocks
EmailService emailService;

...
}
  • We’re using the @Mock annotation to mock DeliveryPlatform, which is automatically injected into our EmailService with the @InjectMocks annotation.

Add an ArgumentCaptor field

  • Second, let’s add a new ArgumentCaptor field of type Email to store our captured argument:
1
2
@Captor
ArgumentCaptor<Email> emailCaptor;

Capture the argument

1
Mockito.verify(platform).deliver(emailCaptor.capture());
  • We can then get the captured value and store it as a new Email object:
1
Email emailCaptorValue = emailCaptor.getValue();

Inspect the captured value

1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void whenDoesSupportHtml_expectHTMLEmailFormat() {
String to = "info@baeldung.com";
String subject = "Using ArgumentCaptor";
String body = "Hey, let'use ArgumentCaptor";

emailService.send(to, subject, body, true);

Mockito.verify(platform).deliver(emailCaptor.capture());
Email value = emailCaptor.getValue();
assertEquals(Format.HTML, value.getFormat());
}

Exception Handling in Spring MVC

HTTP status code

  • HTTP 5XX server error
    • HTTP 500 - internal server error
    • generally, any unhandled exception
    • other 500 errors are generally not used with Spring MVC
  • HTTP 4XX client errors - generally checked exceptions
    • 400 bad request - cannot process due to client error
    • 401 unauthorized - authentication required
    • 404 not found - resource not found
    • 405 method not allowed, HTTP method not allowed

@ResponseStatus

  • allows you to annotate custom exception classes to indicate to the framework the HTTP status you want returned when that exception is thrown
  • global to the application

@ExceptionHandler

  • works at the controller level
  • allows you to define custom exception handling
  • can be used with @ResponseStatus for just printing a http status
  • can be used to return a specific view
  • also can take total control and work with the Model and View
  • Model cannot be a parameter of an ExceptionHandler method

@HandlerExceptionResolver

  • is an interface you can implement for custom exception handling
  • used internally by Spring MVC
  • note Model is not passed

Docker

What is Docker?

  • Docker is a standard for Linux containers
  • a Container is an isolated runtime inside of Linux
  • a Container provides a private machine like space under Linux
  • Containers will run under any modern Linux Kernel

Containers can

  • Have their own process space
  • their own network interface
  • run processes as Root (inside the container)
  • have their own disk space
    • can share with host too
  • Container is not a VM

Docker Terminology

  • Docker Image - the representation of a Docker container, kind of like a JAR or WAR file in Java
  • Docker Container - the standard runtime of Docker, effectively a deployed and running Docker image, like a Spring Boot Executable JAR
  • Docker Engine - the code which manages Docker stuff, creates and runs Docker containers

Notes about Docker Images and Containers

  • Containers are like snapshots of Docker images
  • Docker images are built by Docker files which contains multiple layers, each layer is a Command and will generate a file for the image. The layers will be re-created everytime when we run a new container for an image.
  • e.g. when you docker run -d mongo, a new container for the image mongo will be created, and there is a layer for this container where you can store data in it. But when you docker stop <Container_ID> and re-start using docker run -d mongo, a new container with different Container ID will be created, so your old data in the previous container will not show in your new container. You can map a storage path to the container, so the current container and all future containers will save data into the directory you setup. Which will make the data persistence.

Docker housekeeping

Cleaning up after Docker

  • with development use docker can leave behind a lot of files
  • these files will grow and consume a lot of disk space
  • this is less of an issue on production systems where containers aren’t being built and restarted all the time
  • there are 3 key areas of house keeping
    • containers
    • images
    • volumes

MySQL

MySQL features

  • Stored procedures
    • a piece of code inside of the database that execute against the database, runs locally on the database
  • Triggers
    • when something happens in the database e.g. insert a record, the trigger will run before or after that transaction
  • Cursors
    • point a place in a large set of data so you can scroll through it and look into the next record or previous record.
  • Updated views
    • a virtual table, stored inside the database
  • Query cache
    • database is going to remember in memory the result of your query, when you ask for that data again, it doesn’t have to go back to the file system to get the data.
  • Subselects
    • nested queries.

ACID compliance

  • atomicity - all or nothing
  • consistency - transactions are valid to rules of the DB
  • isolation - results of transactions are as if they are done end to end
  • durability - once a transaction is committed, it remains so (DB will not losing data)

RDBMS deployment architectures

  • typically is driven by needs of scalability and availability
  • can be done on a single non-dedicated server or many dedicated servers
  • communication is typically over a network socket (MySQL: 3306)
  • the client will need software called a driver to talk to the database over the network socket.

MySQL data types

  • a data type defines the data type of a column
  • MySQL does support the standard ANSI SQL data types
  • data types are broken down into the following categories
    • numeric
    • date and time
    • string
    • spatial (location, places)
    • JSON

MySQL installation options

Native installation

  • meaning install on your opearting system

Running MySQL in a Container

  • MySQL can also be run inside a technology called containers
  • Docker is a highly popular container technology
  • through Docker, you can run MySQL locally using pre built image from Docker hub

Connecting to MySQL

  • Local connection
    • connecting to MySQL from the command line on the machine running MySQL
    • to login to docker: docker exec -it yuan-mysql bash
    • to connect to mysql server in Docker: mysql --user=root -p
  • remote / client connection
    • using some type of client software on the same machine running MySQL
    • or connecting to the MySQL server from a different machine over the network

Mongo DB

About Mongo DB

  • Mongo DB is a document oriented database
  • developed in C++
  • MongoDB is a NoSQL database
  • MongoDB documents are stored in BSON
    • binary JSON

Why use Mongo DB?

  • MongoDB is great for high insert systems
    • such as sensor readings, social media systems, advertising systems
  • good when you need schema flexibility
  • can also support a high number of reads per second

Why avoid MongoDB?

  • MongoDB has no concept of transactions
    • No ACID
    • no locking for transactional support, hence faster inserts
  • not good for concurrent updates

Reactive Manifesto

Responsive

  • the system responds in a timely manner
  • responsiveness is the cornerstone of useability and utility
  • responsiveness also means problems may be detected quickly and dealt with effectively
  • responsive systems provide rapid and consistent response times
  • consistent behavior simplifies error handling, builds end user confidence, and encourages further interaction

Resilient

  • system stays responsive in the face of failure
  • resilience is achieved by replication, containment, isolation and delegation
  • failures are contained within each component
  • parts of the system can fail, without compromising the system as a whole
  • recovery of each component is delegated to another
  • high availability is ensured by replication where necessary

Elastic

  • the system stays responsive under varying workload
  • reactive systems can react to changes in the input rate by increasing or decreasing resources allocated to service inputs
  • reactive systems achieve elasticity ina cost effective way on commodity hardware and software platforms

Message Driven

  • reactive systems rely on asynchronous message passing to establish a boundary between components
    • this ensures loose coupling, isolation, and location transparency
  • message passing enables load management, elasticity, and flow control
  • location transparent messaging makes management of failure possible
  • non blocking communication allows recipients to only consume resources while active, leading to less system overhead.

reactive programming with reactive systems

  • reactive programming is a useful implementation technique
  • reactive programming focuses on non-blocking, asynchronous execution - a key characteristic of reactive systems
  • reactive programming is just one tool in building reactive systems

Reactive Programming

  • reactive programming is an asynchronous programming paradigm focused on streams of data
  • reactive programs also maintain a continuous interaction with their environment, but at a speed which is determined by the environment, not the program itself. Interactive programs work at their own pace and mostly deal with communication, while reactive programs only work in response to external demands and mostly deal with accurate interrupt handling, real time programs are usually reactive.

Common use cases

  • external service calls
  • highly concurrent message consumers
  • spreadsheets
  • abstraction over asynchronous processing
    • abstract whether or not your program is synchronous or asynchronous

features opf reactive programming

  • data streams
  • asynchronous
  • non-blocking
  • backpressure
  • failures as messages

data streams

  • data streams can be just about anything
  • mouse clicks, or other user interactions
  • JMS messages, RESTful service calls, Twitter feed, Stock trades, list of data from a database
  • a stream is a sequence of events ordered in time
  • events you want to listen to

Asynchronous

  • events are captured asynchronously
  • a function is defined to execute when an event is emitted
  • another function is defined if an error is emitted
  • another function is defined when complete is emitted

Observer pattern

  • you have a subject and an observer
  • when the subject is going to change, it will notify the observer

Non-blocking

  • the concept of using non blocking is important
  • in blocking, the code will stop and wait for more dta (reading from disk, network etc…)
  • non blocking in contrast, will process available data, ask to be notified when more is available, then continue

back pressure

  • the ability of the subscriber to throttle data

failures as messages

  • exceptions are not thrown in a traditional sense
    • would break processing of stream
  • exceptions are processed by a handler function

Reactive Streams

Spring Reactive Types

  • two new reactive types are introduced with Spring framework 5
  • Mono is a publisher with zero or one elements in data stream
  • Flux is a publisher with zero or MANY elements in the data stream
  • both types implement the reactive streams publisher interface

WebFlux

web MVC webFlux
@Controller, @RequestMapping Router functions
spring-webmvc spring-webflux
Servlet API HTTP / Reactive Streams
Servlet Container Tomcat, Jetty, Netty, Undertow

RESTful web services

  • because of their simplicity and versatility, RESTful web services have become the de facto standard for web services
  • REST - representational state transfer
    • representational - typically JSON or XML
    • state transfer - typically via HTTP

terminology

  • verbs - HTTP methods: GET, PUT, POST, DELETE
  • messages - the payload of the action(JSON / XML)
  • URI - uniform resource identifier
    • a unique string identifying a resource
  • URL - uniform resource locator
    • a URI with network information
  • Idempotence
    • the property of certain operations in mathematics and computer science that they can be applied multiple times without changing the result beyond the initial application
    • in other words, you can exercise the operation multiple times, without changing the result
    • example: refreshing a web page (HTTP GET operation)
  • Stateless - service does not maintain any client state
  • HATEOAS - hypermedia as the engine of application state
    • a REST client should then be able to use server-provided links dynamically to discover all the available actions and resources it needs, as access proceeds, the server responds with text that includes hyperlinks to other actions that are currently available

GET

  • use: to read data from resource
  • read only
  • idempotent
  • safe operation - does not change state of resource

PUT

  • use: to insert or update
  • idempotent - multiple PUT will not change result
  • like saving a file multiple times
  • not safe operation - does change state of resource

POST

  • use: to create new object
  • non-idempotent - multiple POSTs is expected to create multiple objects
  • not safe operation - does change state of resource
  • only non-idempotent, non-safe HTTP verb

DELETE

  • use: to delete an object
  • idempotent - multiple DELETEs will have same effect / behavior
  • not safe operation, does change the state of resource

MapStruct

  • MapStruct is a code generator for Java bean mapping
    • helps reduce coding for type conversions
    • when dealing with Rest services, a common use case is to expose API data using DTOs (Data Transfer Object)
    • as project grows bigger, it is not good to expose POJO directly to Rest services. MapStruct is helping us to convert POJO to DTOs, then export DTOs to Rest service to be consumed by public

Content Negotiation

Content Negotiating view resolver

  • used by Spring MVC to determine view handler to use
  • auto configured by Spring boot
  • the content negotiating view resolver will determine the view to use to render the data of the model to the client

Content type

  • view to use is determined by Content Type in HTTP header
    • application/json, application/xml, text/html
  • if view for requested Content type is not found, HTTP status 406 not acceptable is returned.

Helper Library and Classes

Structure

  • the project should follow a structure from database to frontend: Database -> Repository -> Service -> Controller -> View

JPA

  • H2 in memory database

Thymeleaf

  • frontend template engine, model can be added to view dynamically

Dependency Injection

  • Repositories and Services can be injected when needed, use Annotations @Service, @Component
  • classes marked as @Component, @Service and @Controller will be managed by Spring Application Context, it will inject necessary class to the right place when needed. (Beans)

Configuration

  • config files can be Java, YAML, or XML
  • application.properties can define project profiles

JPA entity relationships

  • One to Many
  • Many to One
  • Many to Many (needs mapping table)

JPA Query methods

  • e.g. findByDescription
  • this is done by the library, findBy + property name
  • library will do the implementations for you

Project Lombok

  • will do the constructors, getters, setters and even builder patterns for you

JUnit

  • Unit Test framework

Mockito

  • for unit tests, we do not want to bring in Spring Application Context
  • so to manage Repositories and Services, we need Mockito to create some Mock component for us
  • when(), thenReturn(), verify(), ArgumentCaptor, MockMvc…

WebJars

  • bring in bootstrap library

Web Data Binder

  • binds HTTP variables to Java object
  • specifically handling form posts and binding form variables to Java data objects
  • whereas Rest service we could use RestTemplate

Validations

  • @NotBlank, @NotNull, @Max, @Min…
  • annotations to data models, for form validations

Exceptions

  • @ResponseStatus
  • @ControllerAdvice
  • dealing with exceptions and custom error messages

Reactive Programming

  • Mono, Flux
  • WebFlux
  • Reactive vs Servlet

RestTemplate

  • bind Rest Response to Java objects

WebClient

  • performing web request

MapStruct

  • auto mapper