FlightPub
FlightClub
Nimbus
Framework
- The secret to success - use a Full-Stack framework.
- Play offers a productive environment for building RESTFUL web apps.
- Download the play-version.zip , unzip, add the play binary to your $PATH and you're good to go:
terminal~/dev$ play new FlightClub
- This generates an intuitive MVC folder hierarchy :
Structure of a app
app → Application sources
└ assets → Compiled asset sources
└ stylesheets → Typically LESS CSS sources
└ javascripts → Typically CoffeeScript sources
└ controllers → Application controllers
└ models → Application business layer
└ views → Templates
build.sbt → Application build script
conf → Configurations files and other non-compiled resources
└ application.conf → Main configuration file
└ routes → Routes definition
public → Public assets
└ stylesheets → CSS files
└ javascripts → Javascript files
└ images → Image files
project → sbt configuration files
lib → Unmanaged libraries dependencies
logs → Standard logs folder
└ application.log → Default log file
REST & ROUTES
- Play! Framework is Stateless and RESTFUL by default
- No Servlets == No servlet containers ( Tomcat, Jetty )
- All requests enter a Play! app via a { java. nio } Non-Blocking I/O Server called Netty that never touches HTTP Session ( ever ).
- Having a static routes file located in the conf directory :
# HTTP
# request URI Controller.method
# type
GET / controllers.Application.index()
GET /FlightSearch controllers.FlightsController.flightSearch()
POST /Login/ResetPassword controllers.SecurityManager.doReset()
DELETE /Cart/Remove controllers.Cart.remove(cartId: Long)
Application.conf
- In the conf folder of the application directory, lives a lonely configuration file: application.conf
- Similar to a Java Properties File:
# Default Routes file: Default to Routes in the root package #application.router=my.application.Routes
# Database configuration # ~~~~~ # You can declare as many datasources as you want. # By convention, the default datasource is named "default" # Uncomment below or use the H2 in-memory database. db.default.driver=com.mysql.jdbc.Driver db.default.url="jdbc:mysql://localhost:3306/flights" db.default.user=... db.default.password=...
- Zero XML configuration
run
- This loads the project and compiles all sources, before deploying it to the configured url:
terminal~/dev/FlightClub$ play run
[info] Loading project definition from /Users/terminal/dev/FlightClub/project
--- (Running the application from SBT, auto-reloading is enabled) ---
[info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
(Server started, use Ctrl+D to stop and go back to the console...)
- Demo to come later ;-)
SBT
- Simple Build Tool - the build tool used by
- Dependency Management
- build.sbt equivalent to maven's pom.xml
name := "FlightClub"
version := "1.0-SNAPSHOT"
libraryDependencies ++= Seq(
javaJdbc,
javaEbean,
cache,
"mysql" % "mysql-connector-java" % "5.1.18"
)
play.Project.playJavaSettings
- SBT compiles both and sources.
SBT
- Reloads code changes on the fly :
--- (Running the application from SBT, auto-reloading is enabled) ---...
[info] Updating {file:/Users/terminal/dev/Flightclub/}flightclub...
[info] Resolving ...
[info] Done updating.
[info] Compiling 3 Scala sources and 2 Java sources to /Users/terminal/dev/Flightclub/target/scala-2.10/classes...
- Means that every update to the code only requires a refresh ( or two ) of the browser.
Relevant Exceptions
- Exceptions are conveniently displayed in the browser :
Ebean ORM & Evolutions
- Ebean is an ORM similar to Hibernate
- HTTP Session-less Transactions
- Highly integrated into Play!
- Evolutions help to handle database migrations
-
Auto-generates sql scripts in response to changes to your @Entity models
- These run at start-up on your database
Evolutions Example
Db
- The Database we were given had no problems at all
- We changed it :
- Indexing
- Normalisation
- Added additional tables to make searching far easier.
- Splitting flights
- Adding routes table
- Migration Scripts
ER Diagram BEFORE
ER Diagram AFTER
WorkFlow
Jira Wallboard
Demo
Paul
- Flight Search approach
- Server vs Client-side templating
- Views
- views.scala.html templates
- Responsive design
Lachlan
- Compiled Assets
- LESS CSS
- CoffeeScript
- Forms & Data-Validation
Coffee vs JS
Coffee & for-each
Coffee & Expressions
Forms & Validation
Form<User> userForm = form(User.class);
@Entity public class User { @Constraints.Required @Constraints.Email public String email; @Constraints.MinLength(6) public String password; public String validate() { if(authenticate(email,password) == null) { return "Invalid email or password"; } return null; } }
if(userForm.hasErrors()) {
return badRequest(form.render(userForm));
} else {
User user = userForm.get();
return ok("Got user " + user);
}
LESS.CSS
Variables are pretty easy
@black: #FFCC00
#header{
color: @black
}
Mixins are an easy way of including properties from one rule-set to another.
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
#menu a {
color: #111;
.bordered;
}
Nesting Rules
#header {
color: black;
.navigation {
font-size: 12px;
}
.logo {
width: 300px;
}
}
Previous Designs
Less Professional;
Poor Bootstrap Integration
Login in Header
Poor adaptation for Mobile
Near completion
Current
FlightClub
By Jonathon Hope
FlightClub
A presentation on a software engineering project featuring the technology stack and our workflow.
- 1,055