-
Notifications
You must be signed in to change notification settings - Fork 0
summaries
Miguel Gamboa edited this page Dec 13, 2024
·
55 revisions
Lessons:
- 09-09-2024 - Lesson 01 - DAW intro and distinguish from IPW and LS
- 09-09-2024 - Lesson 02 - Spring Framework Intro
- 13-09-2024 - Lesson 03 - Spring Controller life-cycle, Dependencies and Beans
- 16-09-2024 - Lesson 04 - DI and IoC (Dependency Injection and Inversion of Control)
- 16-09-2024 - Lesson 05 - IoC/DI Container
- 20-09-2024 - Lesson 06 - Bean functions; Servlet API;
- 23-09-2024 - Lesson 07 - Spring Arguments Binding and MessageConverter
- 23-09-2024 - Lesson 08 - Lab 1 - Filter, Interceptor and Arguments Resolver
- 27-09-2024 - Lesson 09 - Organizing and testing backend software
- 30-09-2024 - Lesson 10 - Lab 2 - Project - part 1
- 30-09-2024 - Lesson 11 - Lab 3 - Project - part 1
-
04-10-2024 - Lesson 12 - HTTP API; RFC 7807 Problem Details;
Either
;TransactionManager
-
07-10-2024 - Lesson 13 - Lesson 13 - JDBI;
repository-jdbi
; Docker; Parameterized Tests; - 07-10-2024 - Lesson 14 - Lab 4 - Project - part 1
- 11-10-2024 - Lesson 15 - Environment Configuration, Setup and Teardown; CI;
- 14-10-2024 - Lesson 16 - SignUp; Login; Authentication Tokens;
- 14-10-2024 - Lesson 17 - Lab 5 - Project - part 1
- 18-10-2024 - Lesson 18 - Server-sent events (SSE)
- 21-10-2024 - Lesson 19 - Project Phase 1 - presentations
- 21-10-2024 - Lesson 20 - Project Phase 1 - presentations
- 25-10-2024 - Lesson 21 - TypeScript Introduction
- 28-10-2024 - Lesson 22 - Browser as JS host
- 28-10-2024 - Lesson 23 - Modules: CommonJs vs ESM; Bundler e.g. WebPack
- 04-11-2024 - Lesson 24 - React Intro; React and ReactDom API; JSX;
- 04-11-2024 - Lesson 25 - Reconciliation; React Components;
- 08-11-2024 - Lesson 26 - State and React Hooks
- 11-11-2024 - Lesson 27 - Effects
-
11-11-2024 - Lesson 28 -
useEffect
Hook -
15-11-2024 - Lesson 29 -
useReducer
Hook - 18-11-2024 - Lesson 30 - Client-side routing
- 18-11-2024 - Lesson 31 - Lab 6 - Project - part 2
- 22-11-2024 - Lesson 32 - Deep Linking; CORS; Authentication; React Context Intro;
- 25-11-2024 - Lesson 33 - React Context; Authentication; Form handling and state machine;
- 18-11-2024 - Lesson 34 - Lab 7 - Project - part 2
- 29-11-2024 - Lesson 35 - Automatic Browser Testing; Lab 8 - Project - part 2
- 02-12-2024 - Lesson 36 - Lab 9 (zoom) - Project - part 2
- 02-12-2024 - Lesson 37 - Lab 10 (zoom) - Project - part 2
- 09-12-2024 - Lesson 38 - Project Phase 2 - presentations
- 09-12-2024 - Lesson 39 - Project Phase 2 - presentations
- 13-12-2024 - Lesson 40 - Deployment and Load Balancing
- SSR
!=
CSR - IPW uses SSR (Server Side Rendering)
- LS uses CSR (Client Side Rendering)
- CSR
=>
JavaScript +fetch
API - FrontEnd with partial updates:
- Example appending HTML fragment to an HTML page
- BackEnd with Spring Framework (1st half of semester):
- Equivalent do Express in IPW but with different approach and tech (JVM)
- Spring may be used with an HTTP Server such as jetty, Tomcat, or other
- FrontEnd (2nd half of semester):
- React library and TypeScript programming language
- WebPack module bundler
- Introduction to Spring Framework
- Spring Initializr
- Dependency for Spring Web (NOT Spring Reactive Web).
- Review Gradle Wrapper
- Review build.gradle.kts
- Analyze dependencies
- Development Environment and Practices
- Build the Spring project and run the
jar
- Comparing Spring Controllers
!=
Express Routes - Annotation
@RestController
and annotation@GetMapping
- Testing with the browser and in terminal with
curl
- Analyzing the
Content-Type
response header andAccept
request header - Content negotiation
-
Homework:
- Request
curl -i http://localhost:8080/hello
and theContent-Type
istext/plain;charset=UTF-8
- Request from a browser responds with
Content-Type
nowtext/html; charset=UTF-8
. - QUESTION: Can you change the curl request command to has the response also
with the
text/html
media type?
- Request
- Controller life-cycle
- Using logging statements and multiple HTTP requests observe how many
ControllerExample
instances are created?- One instance by default. This behavior can be changed.
- Observe the identifiers of the threads where the handler methods are called.
- One instance whose handlers (methods) are invoked by multiple threads
- QUESTION: given the observations, what should be the restrictions to the instance state?
-
ControllerExample
---->
ServiceGreetings
(interface) -
ControllerExample
has a dependency ofServiceGreetings
(interface):- We need an instance of a class compatible with
ServiceGreetings
to instantiateControllerExample
- We need an instance of a class compatible with
- Spring has to resolve the dependency.
- How Spring instantiates
ControllerExample
?- ERROR:
Parameter 0 of constructor in ControllerExample required a bean of type 'ServiceGreetings' that could not be found.
- ERROR:
- Class implementing
ServiceGreetings
must have the@Component
annotation. - Classpath scanning and managed components -
@Component
- Bean - "an object that is instantiated, assembled, and managed by a Spring container".
- Spring Container is called Context
- Review Spring Basics: Controller, Handlers, Component and Bean.
- Inversion of Control Containers and the Dependency Injection pattern
- Example of
MovieLister
-->
MovieFinder
-->
DataSourceClient
- Only the leafs of a dependency graph have no dependencies.
- Mock - "an object that imitates a production object"
- Implementing
MovieFinderMock
- Property Injection versus Constructor Injection
- Implementation of a simple DI and IoC function
loadInstanceOf(klass: KClass<T>) : T
- Context - In the Spring Framework, the IoC container is often referred to as context.
-
AnnotationConfigApplicationContext
-scan()
,refresh()
,getBean()
-
Scope
:singleton
(by default) versusprototype
- Lists injection
- Example of
MovieLister
-->
MovieFinder
-->
DataSourceClientViaHttpClient
-->
HttpClient
-
@Bean
- marks a bean function
- HTTP servlet API:
HttpServlet
andHttpFilter
-
HttpServlet
:doGet(HttpServletRequest, HttpServletResponse)
-
HttpFilter
:doFilter(HttpServletRequest, HttpServletResponse, FilterChain)
-
-
Servlet Container:
- implements and manages instances of
HttpServletRequest
,HttpServletResponse
,FilterChain
. - "contains and manages servlets through their lifecycle."
- e.g. Jetty, Tomcat, etc
- implements and manages instances of
- Servlet and Filter Pipeline
- E.g. running
ExampleServlet
andExampleFilter
on Tomcat or Jetty
- HTTP Servlet API
◄---
Spring MVC--->
Servlet Container -
@PathVariable
- Binding path variables to arguments. -
@RequestParam
- Binding query string values to arguments (Nullable for optional). -
@RequestBody
- Binding HTTP request body in JSON to an argument. - Bean Validation - "Express validation rules in a standardized way using annotation-based constraints"
- Dependency =>
spring-boot-starter-validation
=>@Valid
- Built-in return value handling in Spring: String and JSON
-
WebMvcConfigurer
- configure Argument Resolvers and Message ConvertersHandlerMethodArgumentResolver
-
AbstractGenericHttpMessageConverter
=> Processing the HTTP body (request and/or response).
-
Filters ->
DispatcherServlet
-> Interceptors -> Arg resolution | Return value handling -> Handlers -
HandlerMethod
- represents a Spring handler in a Controller instance.
- Review - Spring Web MVC provides:
- DI + Controllers/Handlers management + HTTP Server integration
- Mapping between HTTP protocol <-> Controller handlers
- Why a Service?
-
Service
-->
Domain<--
Repository - Different implementations of Repository: JDBI, JPA, other.
-
Domain model:
- immutable;
- no side-effects;
- has no dependencies on Service or Repository.
- Use case for Agendify web app (~ e.g. Doodle)
- Testing the Service with Repositories mocks.
- MockK - mocking library for Kotlin.
- Resource: Backend Code organization by Pedro Felix
- Maintain the domain model with associations that have single multiplicity.
- Managing Many-to-One relationships at the Repository Level.
- Manage Database connections and transactions;
-
TransactionManager
---new-->
Transaction
--uses/new-->*
Repository
/**
* block > operations using the repositories provided by a Transaction,
* e.g. createParticipant:
* 1. repoParticipants.findByEmail(email) // return Failure if already exist
* 2. repoParticipants.createParticipant(name, email, kind)
*/
interface TransactionManager { fun <R> run(block: Transaction.() -> R) : R }
-
TransactionManager
life-cycle managed by DI/IoC container -
Transaction
life-cycle out of the scope of the DI/IoC container (managed by aTransactionManager
). -
Either<L,R>
- Strongly typed representation of failure. -
Controller should handle all types of
Failure
(i.e.Either.Left
) returned by a Service. - RFC 7807 - Problem Details for HTTP APIs
- Auxiliary sealed class
Problem
to manageapplication/problem+json
responses. WebTestClient
- Lecture Notes by Pedro Felix:
- JDBI (Java Database Interface) - high-level library that simplifies JDBC interactions.
- JDBI
Handle
- connection wrapper that manages database interaction and lifecycle. -
repository-jdbi
-TransactionManager
onrun(block)
:- manages an
Handle
perTransaction
; - a
Transaction
instantiates repositories with givenHandle
.
- manages an
-
repository-jdbi
folders:-
/src/sql
containscreate-schema.sql
-
/tests
contains docker fileDockerfile-db-test
to build a Docker image to run Postgres. -
/tests/scripts/wait-for-postgres.sh
- checks when PostgreSQL is running and ready to accept connections.
-
-
Dockerfile
<---
Image
<---*
Container
:- Dockerfile: contains instructions for building a Docker image.
- Image: read-only template used to create containers.
- Container: isolated execution environment that packages an application and its dependencies.
- "The same way that processes are created from executable files, containers are created from container images."
- Running Service tests with different repository implementations, such as in-memory and JDBI.
- Junit Jupiter API for
@ParameterizedTest
and@MethodSource
- Make the Gradle test task dependent on Docker Compose to manage the PostgreSQL container lifecycle.
-
Docker Compose tool for running multi-container Docker applications:
-
Service: Represents a single container, e.g.
db-tests
-
docker-compose.yml
- configuration file. -
docker compose up
- start the application by creating and starting all services. -
docker-compose down
- stops and removes containers.
-
Service: Represents a single container, e.g.
- Syntax style rules and enforcement, e.g. using ktlint
- Continuous integration and continuous check, e.g. using GitHub actions
- Using secrets in GitHub Actions
- Project
agendify
classEnvironment
getsDB_URL
from env variable. - Running
http-api
tests with different implementations of repository: in-memory and JDBI. - Context configuration with Profiles:
spring.main.allow-bean-definition-overriding=true
-
@Profile
- associate a Bean or configuration to a Profile -
@ActiveProfiles
- select the profile to be activated with the context.
- Module
host
- Authentication flow:
- 👤
-- username/password -------------->
login-->
token - 👤
-- Authorization: Bearer <token> -->
validate; find user; ... - 👤
-- Authorization: ...
...
- 👤
- Bearer authentication scheme
-
TokenEncoder
:- takes a token and produces a validation information that can be stored in the database.
- the token should be hard to compute from this information, but easy to validate.
- Configurations: TTL and maximum number of tokens per user.
- HTTP pipeline:
-
AuthenticationInterceptor
:- Checks if the handler requires authentication.
- If so, verifies the token and retrieves the associated user.
- Add an
AuthenticatedUser
object to the request attributes.
-
AuthenticatedUserArgumentResolver
- Applied to handlers with an
AuthenticatedUser
argument. - Retrieves the
AuthenticatedUser
object from the request attributes.
- Applied to handlers with an
-
- Using client established connections to send server initiated events.
- Sending events in the context of an unfinished response.
- The Server-sent Events specification, namely its media-type:
text/event-stream
-
Last-Event-ID
HTTP request header and theEventSource
object reestablishing the connection. - Keep Alice ~ comment line (one starting with a
:
character) - Spring MVC support for the SSE specification:
SseEmitter
class.
- Implementing route on Agendify Web App to listen SSE for updated
TimeSlot
instances.
- TypeScript type system.
- Primitive types:
string
,number
, andboolean
. - Type
any
- Object types.
- Optional properties -
<prop name>?:...
-
Structural Type System:
- "type checking focuses on the shape that values have."
-
Type alias - a name for any type. Syntax:
type <name> = ...
-
interface
=> an open type, which is always extendable. - Unions, discriminated unions, and type narrowing.
- Generics
- Arrays
- See: TypeScript for JavaScript Programmers
- Exercises:
- Fix the TypeScript code in the following TypeScript Playground
- Exercise on the TypeScript type system
- HTML tag
script
to embed or refer to JavaScript code. - Without modules support:
- No isolation between different JS files
- Declarations visible in global scope
- Demo: conflict between top-level declarations in different JS files
-
<script type="module" ...
- causes the code to be treated as an ES module:- The processing of the script contents is deferred
- That module may import other ES modules => HTTP request to that resource.
-
Common JS modules via JS API: object
exports
and functionrequire
-
EcmaScript modules keywords:
export
andimport
- Demo:
main.js
-->
lib1.js
-->
lib2.js
- Comparing dependency resolution on Node vs Browser--HTTP server
- NO native Browser support for Common JS modules
- The motivation for an application build step:
- transforming the source files into the resources provided to the browser.
-
Bundling may include:
- reduction of the HTTP requests needed to load the script resources.
- Minification - reduction of the script size.
- "transpiling" (Source-to-source compiler):
- translate different language on the source files, namely TypeScript.
- translate unsupported Browser features, e.g. Common JS.
-
webpack
andwebpack-cli
:-
src
anddist
- bundling, minifying and "transpiling"
-
-
GUI development approaches: From Imperative to Declarative:
- Imperative e.g. AWT, Windows Forms, GWT, others
- Declarative e.g. React, Jetpack Compose, Flutter, others
-
React approach:
- GUI = Tree
- State is Immutable
- life-cycle: S1
->
S2->
...->
SN - f(model) => Tree
- Frontend Dev Environment:
- Dev dependencies: Webpack, Typecript, React and React DOM
-
Config: Typecript and Webpack config:
ts-loader
-
HTTP server:
serve
,webpack-dev-server
, or other
- React and ReactDom API
- Virtual Tree != DOM Tree
-
JSX:
- Syntax extension for JavaScript that lets you write HTML-like markup within JavaScript
- Like a web template syntax WITHOUT the need of special control flow dialects like
#each
,:each
, and others
-
Reconciliation: Virtual Tree
=>
DOM Tree- "React can decide exactly which components in the tree need re-rendering and skip over the ones that don’t."
- Defining components and creating elements using components.
-
React Components as pure functions:
- Idempotent – the same result for the same inputs
- No side effects
- Does not mutate non-local values:
-
React Components:
- Never call component functions directly
- Don’t call them as regular functions.
- Components should only be used in JSX.
- React should call it.
- Passing properties JSX to React Component
- "Components need to "remember" things"
-
State
=>
"A Component's Memory" - How to manage State in Functional Components?
- Global State?? AVOID mutable global state
- Instance Fields?? NO Gui components through classes definition
- Closures?? NO adequate isolation
- DON'T DO THIS:
let count = 0
function Counter({}) {
return (
<div>
<button onClick={() => {count++; root.render((<Counter/>))}}>
+
</button>
...
- Hooks: special functions ONLY available while React is rendering
- let you “hook into” different React features.
- You “use” React features at the top of your component, similar to how you “import” modules at the top of your file.
- E.g.
useState
, you are telling React that you want this component to remember something. -
WITHOUT a conditional order between several uses of
useSate()
!!!! - Hooks rely on a stable call order on every render of the same component.
-
useState
gives you an array containing 2 values:- The state variable with the value you stored.
- The state setter function .
-
=>
trigger React to render the component again.
-
- State is ISOLATED and PRIVATE
- If you render the same component twice, each copy will have completely isolated state!
- State is fully private to the component declaring it.
- State management reviews;
- Example: implementation of a
TextFieldValidator
Component.
- REMEMBER: React Components as pure functions:
- Idempotent – the same result for the same inputs
- Does not mutate non-local values:
- No side effects
- DON'T DO THIS: Example of a recursive loop caused by improper use of side effects:
function FetchAndShow({uri}: {uri: string}) {
const [respBody, setRespBody] = React.useState("")
fetch(uri) /* DON'T DO THIS!!!! */
.then(resp => resp.text())
.then(body => setRespBody(body) /* Runs after rendering is complete */ )
return (...)
}
-
Infinite recursion: render
->
FetchAndShow()
->
fetch
->
render completion ->fetch
completion->
setRespBody
->
render->
FetchAndShow()
->
fetch
->
render completion ->fetch
completion->
setRespBody
->
render->
...
- Effects - Run after render.
-
useEffect(callback, [dependency, ...])
- schedule an effect -
effect dependencies:
- array of values;
- if present, effect will only activate if the values in the list change.
useEffect(() => { ... return Cleanup Function }, [dependency, ...])
-
Cleanup Function
- called if a component is Unmounted.
- called each time before the Effect runs again.
- Some operations, such as fetch, cannot be easily canceled:
- In that case, we may choose to cancel subsequent UI updates.
- Example: implementation of a
StopWatch
Component.
-
WeakChecker
: React component to check for security leaks, such as length, use of numbers, special characters, avoidance of common weak passwords, etc.- version 1: synchronous validation.
- version 2: asynchronous validation through an external service.
- Validate password only after user stops typing
=>
usesetTimeout
- !!! RACE condition between last validation error and current input value.
-
reduce:
function reduce(State, Action): State
const [state, dispatch]: useReducer(reduce, { <Initial State> })
- React Component
=>
dispatch(<instance of Action>)
-
Exercise React hooks - Make a new implementation with
useReducer
- server-side routing
<versus>
client-side routing - The concept of client-side routing.
- The browser
history
API for changing the navigation history. - Introduction to the React Router library.
- Redirection between routes.
-
<Outlet>
- in parent route elements to render their child route elements.
- Deep Linking
- Webpack
devServer.historyApiFallback
- using the HTML5 History API, theindex.html
page will likely have to be served in place of any 404 responses
- Origin: combination of a scheme (e.g. HTTP or HTTPS), a hostname, and a port.
- CORS - cross origin resource sharing
- A server returning
Access-Control-Allow-Origin: *
means that the resource can be accessed by any ORIGIN. - Using the webpack-dev-server to proxy requests to the HTTP API, as a way to avoid cross-origin requests.
- Using Cookies for storing and transporting authentication tokens.
- Comparison between Cookie usage and the
Authorization
header with explicit storage. -
Set-Cookie
attributes:- The
httpOnly
attribute and the protection against XSS attacks. - The
SameSite
attribute and the protection against CSRF attacks. - The
secure
attribute.
- The
- The context concept in React.
- React Context API:
-
Definition:
- Define the type of context
T
-
createContext<T>(): Context<T>
: Creates a new context object for the typeT
. -
Context<T>.Provider
: A React component used to provide the context value to its descendants.
- Define the type of context
-
Provider:
- Supplies a value to its descendants via the
Context<T>.Provider
component, e.g. used in JSX.
- Supplies a value to its descendants via the
-
Consumers:
- Components that are descendants of the
Provider
and access the context value. - Use the
useContext(Context<T>): T
hook to consume the provided context value.
- Components that are descendants of the
-
Definition:
- React Context API
- Example:
ThemeContextType
,ThemeContext
,ThemeProvider
,ThemeSwitcher
- Example for Authentication:
AuthContextType
,AuthContext
,AuthProvider
- Example of Authentication consumers:
-
Home
- displays logged user profile -
Login
- updates logged user viasetUser
of theAuthContext
-
AuthRequire
- wraps Components requiring authentication and redirects toLogin
-
- React Router DOM:
-
Navigate
component -
Location
- contains information about the URL path, as well as possibly some arbitrary state and a key.
-
- Login form
- Distinguish between SSR redirect and CSR redirect.
- Form state machine:
editing
,submitting
,redirect
- Form actions:
edit
,submit
,success
,error
- Playwright - Automation framework for Browser Testing.
- Playwright supports rendering engines including Chromium, WebKit, and Firefox.
- Installation through
npm init playwright@latest
:- Name of your Tests folder (default is tests)
- Add a GitHub Actions workflow to easily run tests on CI
- Install Playwright browsers (default is true)
- Scripts on
package.json
:"test": "npx playwright test"
"test-report": "npx playwright show-report"
- Configure local dev server on
playwright.config.ts
:
webServer: {
command: 'npm run start',
url: 'http://127.0.0.1:8000',
reuseExistingServer: !process.env.CI,
}
-
assemble
- builds a fat or Uber JAR containing the application classes and all dependency JARs. -
./gradlew :lesson15-host:assemble
--->
lesson15-host-0.1.0-SNAPSHOT.jar
(fat or Uber JAR):-
META-INF
- Contains metadata, including theMANIFEST.MF
with metadata such as the main class and classpath. -
BOOT-INF/lib
- all the external dependencies (JAR files), e.g.jackson-annotations-2.17.2.jar
,lesson09-agendify-domain-0.1.0.jar
, etc -
BOOT-INF/classes
- your application's compiled classes, e.g.AppAgendify.class
,Environment.class
, etc -
org/springframework/boot/loader/
- classes responsible for loading the Spring Boot application from the Uber JAR.
-
- Build JVM Image with agendify Spring MVC web application:
-
assemble
- builds the Uber Jar -
extractUberJar
- extract classes and JARs from the Uber JAR intobuild/dependency
folder - Uses the
openjdk:21
image as the base and copies the extracted contents frombuild/dependency
to the container's/app
directory.
-
- Load balancing
- Improving performance via horizontal scaling.
- High availability by using multiple nodes.
- Balancing policies, such as "round-robin".
- Retry policies.