inakianduaga / scala-play-car-advert Goto Github PK
View Code? Open in Web Editor NEWScala Play Restful example app w/ AWS DynamoDB integration
License: Other
Scala Play Restful example app w/ AWS DynamoDB integration
License: Other
The current CORS filter is working but we should write a test for it.
Seems Java SDK has a convenient way of wrapping dynamodb operations by annotating properties of the case classes (although this would couple the case class which represents data with the storage implementation, so probably not nice unless it can be done on a separate file).
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.html
http://stackoverflow.com/questions/17070253/how-can-one-use-amazons-dynamodbmapper-in-scala
This provides a way to do the same using the json document format
https://aws.amazon.com/blogs/aws/dynamodb-update-json-and-more/
seems the better approach
For both models we can do validation on the constructor by using something like
http://stackoverflow.com/questions/20478588/scala-case-class-how-to-validate-constructors-parameters
Then we can see if we return Option/Maybe
or Try
Update: Better to use Try
to handle possible validation exceptions
Using Try has the disadvantage of making it hard to differentiate the different errors (such as NotFound vs Validation errors, etc). Instead, we should go for something like
Where the different errors are defined as a sealed Trait
sealed trait MyError
case class UnknownUser(userId: Long) extends MyError {
override def toString = s"User with id [$userId] is unknown."
}
case class WrongSecret(userId: Long) extends MyError {
override def toString = s"User with id [$userId] provided the wrong secret."
}
case class ServiceUnavailable(service: String) extends MyError {
override def toString = s"The Service [$service] is currently unavailable"
}
Car adverts should have the following fields:
Since the payload to generate a car is smaller than the response (which contains an additional id), best way to do it DRY is to have a base model for the submission/update payloads and an extended model used for the responses
The data flow is
controller (raw json) -> `hydrated CarAdvert` -> StorageDriverTrait -> StorableTypeTrait -> `hydratedCarAdvert` -> raw json
Either[AdvertNewCar,AdvertUsedCar]
. If we do that then it becomes easy toWe need a service that will hydrate/convert between the database StorableTrait
input/output types and the AdvertNewCar/AdvertUsedCar
types.
Service needs to:
AdvertNewCar,AdvertUsedCar
already implement StorableType.We want to containerize the app
https://github.com/scoverage/sbt-coveralls
It also integrates w/ Travis so bonus points for that
The following is brainstorming how to best setup the database access layer
StorageDriverTrait
: An interface that has CRUD get/delete/update/create
methods and
DynamoDbStorage
: The actual implementation, constructs JSON from each of the models (the modes I guess should have a toJson method), and an object companion fromJson probably as wellWe want to be able to serve requests from different domains than where the server is hosted client-side, so we need to pass browser CORS tests
https://www.playframework.com/documentation/2.5.x/CorsFilter
We want to build the application (and pass tests) on PR/merges through travis. Optionally perhaps deploy to Heroku, depending on how we deploy the application
https://docs.travis-ci.com/user/docker/
See Inaki's CV Travis config as an example of running a dockerized build
Once the Rest server is up and running, we can add integration tests using play-ws
Another possibility is to generate the API client from the swagger spec via Scala Swagger codegen
Either start with sbt file from scratch or use one of the given activators
Right now the DynamoDB client is generated in the DynamoDB storage class, this makes it that we have to choose between production & local there. It would be cleaner to have that decision outside and inject the client via Guice.
http://stackoverflow.com/questions/36635128/how-can-i-generalize-either-to-more-and-recursive-types
We need to have 2 case classes:
We also need a base AdvertTrait
that implements all the shared methods, such as validate (or maybe not validate since if the object is created the data must be valid already), perhaps as a object companion static method without implementation.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.