Skip to content

Commit

Permalink
Demo API with JSON response
Browse files Browse the repository at this point in the history
  • Loading branch information
nguyentoanit committed Nov 27, 2018
1 parent 533f19e commit 21b9b60
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 15 deletions.
66 changes: 66 additions & 0 deletions app/application/API.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package application
import play.api.mvc._
import play.api.libs.json._
import play.api.libs.functional.syntax._
import javax.inject._

case class Location(lat: Double, long: Double)

case class Place(name: String, location: Location)

object Place {
var list: List[Place] = {
List(
Place(
"Sandleford",
Location(51.377797, -1.318965)
),
Place(
"Watership Down",
Location(51.235685, -1.309197)
)
)
}
def save(place: Place) = {
list = list ::: List(place)
}
}
class ApiApplication @Inject() (cc: ControllerComponents) extends AbstractController(cc) {
implicit val locationWrites: Writes[Location] = (
(__ \ "lat").write[Double] and
(__ \ "long").write[Double]
)(unlift(Location.unapply))

implicit val placeWrites: Writes[Place] = (
(__ \ "name").write[String] and
(__ \ "location").write[Location]
)(unlift(Place.unapply))

implicit val locationReads: Reads[Location] = (
(__ \ "lat").read[Double] and
(__ \ "long").read[Double]
)(Location.apply _)

implicit val placeReads: Reads[Place] = (
(__ \ "name").read[String] and
(__ \ "location").read[Location]
)(Place.apply _)

def listPlaces = Action {
val json = Json.toJson(Place.list)
Ok(json)
}

def savePlace = Action(parse.json) { request =>
val placeResult = request.body.validate[Place]
placeResult.fold(
errors => {
BadRequest(Json.obj("status" -> "KO", "message" -> JsError.toJson(errors)))
},
place => {
Place.save(place)
Ok(Json.obj("status" -> "OK", "message" -> ("Place '" + place.name + "' saved.")))
}
)
}
}
8 changes: 4 additions & 4 deletions app/application/AccountApplication.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package application

import application.forms.Account.{ passwordCheckConstraint, usernameCheckConstraint }
import application.forms.Account.{passwordCheckConstraint, usernameCheckConstraint}
import application.forms.CreatingInput
import domain.Account.entity.Account
import domain.Account.repository.AccountRepository
import javax.inject.{ Inject, Singleton }
import javax.inject.{Inject, Singleton}
import play.api.data.Form
import play.api.data.Forms._
import play.api.i18n.{ Lang, Messages }
import play.api.mvc.{ AbstractController, ControllerComponents, EssentialAction }
import play.api.i18n.{Lang, Messages}
import play.api.mvc.{AbstractController, ControllerComponents, EssentialAction}
import application.forms.LoginData
import application.forms.Login.loginForm

Expand Down
2 changes: 1 addition & 1 deletion app/application/forms/Account.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package application.forms

import play.api.data.Forms._
import play.api.data._
import play.api.data.validation.{ Constraint, Invalid, Valid }
import play.api.data.validation.{Constraint, Invalid, Valid}

case class CreatingInput(username: String, mailAddress: String, password: String, repeatedPassword: String) {
require(password == repeatedPassword, "Password not match")
Expand Down
8 changes: 4 additions & 4 deletions app/domain/Account/entity/Account.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import javax.validation.constraints._

case class Account(usernameParam: String, emailParam: String, passwordParam: String, idParam: Long = 0L) {
@NotNull(message = "name is required")
@Max(value = 50, message = "max lenth of name is 50 characters")
@Max(value = 50, message = "max lenth of name is 50 characters")
val username: String = usernameParam

@NotNull(message = "email is required")
@Email(message = "email is not valid")
val email: String = emailParam

@Max(value = 20, message = "max lenth of password is 20 characters")
@Min(value = 8, message = "password is weak")
@Max(value = 20, message = "max lenth of password is 20 characters")
@Min(value = 8, message = "password is weak")
@Pattern(
regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])$",
regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])$",
message = "password must contain at lease one lower case letter, one upper case letter and one digit"
)
val password: String = passwordParam
Expand Down
3 changes: 2 additions & 1 deletion app/domain/Account/repository/AccountRepository.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ class AccountRepository @Inject() (dao: AccountDAO) {
try {
val id: Long = dao.store(toDTO(input))
Right(Account(input.username, input.email, input.password, id))
} catch {
}
catch {
case e: SQLException => Left(e.getMessage)
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/domain/Article/entity/Article.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package domain.Article.entity

import java.util.Date

import domain.Article.valueobject.{ ArticleID, FilePath }
import domain.Article.valueobject.{ArticleID, FilePath}

case class Article(title: String, thumbnail: FilePath, content: String, id: ArticleID = null, createdAt: Date = null, updatedAt: Date = null) {
require(title.length > 0, "title is required")
Expand Down
2 changes: 1 addition & 1 deletion app/domain/Article/repository/ArticleRepository.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package domain.Article.repository

import domain.Article.entity.Article
import domain.Article.valueobject.{ ArticleID, FilePath }
import domain.Article.valueobject.{ArticleID, FilePath}
import exception.EntityNotFoundException
import infrastructure.dao.ArticleDAO
import infrastructure.dto.ArticleDTO
Expand Down
6 changes: 3 additions & 3 deletions app/infrastructure/dao/ArticleDAO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ private object ArticleDAO extends SQLSyntaxSupport[ArticleDTO] {

def apply(a: ResultName[ArticleDTO])(rs: WrappedResultSet): ArticleDTO =
ArticleDTO(
id = rs.long(a.id),
title = rs.string(a.title),
id = rs.long(a.id),
title = rs.string(a.title),
thumbnail = rs.string(a.thumbnail),
content = rs.string(a.content),
content = rs.string(a.content),
createdAt = rs.date(a.createdAt),
updatedAt = rs.date(a.updatedAt)
)
Expand Down
3 changes: 3 additions & 0 deletions conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ GET /account/create application.AccountApplication.show
POST /account/create application.AccountApplication.create
POST /login application.AccountApplication.login

GET /places application.ApiApplication.listPlaces
POST /places application.ApiApplication.savePlace

# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)

0 comments on commit 21b9b60

Please sign in to comment.