Coder Social home page Coder Social logo

inakianduaga / scala-play-car-advert Goto Github PK

View Code? Open in Web Editor NEW
2.0 2.0 0.0 1.11 MB

Scala Play Restful example app w/ AWS DynamoDB integration

Home Page: http://petstore.swagger.io/?url=http://scala-play-car-advert.herokuapp.com/swagger/car/adverts/spec.yml

License: Other

Scala 97.51% Shell 2.49%
aws-dynamodb scala

scala-play-car-advert's People

Stargazers

 avatar  avatar

scala-play-car-advert's Issues

Scala DynamoDB access

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

Update

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

Use Either w/ ADT error class to handle different exception types

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

http://mavilein.github.io/scala/2015/09/01/comparing-error-handling-scalas-try-with-scalazs-either-disjunction/

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"
}

Create swagger spec document

Specs

Car adverts should have the following fields:

  • id (required): int or guid, choose whatever is more convenient for you;
  • title (required): string, e.g. "Audi A4 Avant";
  • fuel (required): gasoline or diesel, use some type which could be extended in the future by adding additional fuel types;
  • price (required): integer;
  • new (required): boolean, indicates if car is new or used;
  • mileage (only for used cars): integer;
  • first registration (only for used cars): date without time.

Models

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

Editor

Controller data flow

The data flow is

controller (raw json) -> `hydrated CarAdvert` -> StorageDriverTrait -> StorableTypeTrait -> `hydratedCarAdvert`  -> raw json

Json service

  • We need some logic to convert from the raw input json into an Either[AdvertNewCar,AdvertUsedCar]. If we do that then it becomes easy to
  • We need logic to convert to raw json.
  • Write tests for the Json service

Hydrate Service

We need a service that will hydrate/convert between the database StorableTrait input/output types and the AdvertNewCar/AdvertUsedCar types.

Service needs to:

  • Given a StorableType, it needs to convert it into an Either[AdvertNewCar,AdvertUsedCar]. The other direction is already satisfied, since the AdvertNewCar,AdvertUsedCar already implement StorableType.

Setup docker containers

We want to containerize the app

  • Docker container for the play app running through sbt
  • Docker container for DynamoDB database

Fix controller methods

Create method

  • Success creating new car advert
  • Success creating used car advert
  • Check exceptions

Scala database code structure

Idea:

The following is brainstorming how to best setup the database access layer

  • StorageDriverTrait: An interface that has CRUD get/delete/update/create methods and
    • takes the full models Either(CarAdvertNew|CarAdvertUsed) as parameters.
      -This will return the same for the getter methods (with an optional collection). The actual storage format is invisible to the user.
  • 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 well

Move DynamoDB client to be dependency-injected

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.

Car advert classes

http://stackoverflow.com/questions/36635128/how-can-i-generalize-either-to-more-and-recursive-types

We need to have 2 case classes:

  • AdvertForNewCar
  • AdvertForUsedCar
    and use scala Either to wrap them into different return cases. (at the end of the day the only thing that will change will be the validation).

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.