├── project ├── build.properties └── plugins.sbt ├── src ├── main │ ├── resources │ │ ├── swagger │ │ │ ├── images │ │ │ │ ├── expand.gif │ │ │ │ ├── collapse.gif │ │ │ │ ├── favicon.ico │ │ │ │ ├── throbber.gif │ │ │ │ ├── logo_small.png │ │ │ │ ├── wordnik_api.png │ │ │ │ ├── explorer_icons.png │ │ │ │ ├── favicon-16x16.png │ │ │ │ ├── favicon-32x32.png │ │ │ │ └── pet_store_api.png │ │ │ ├── fonts │ │ │ │ ├── DroidSans.ttf │ │ │ │ └── DroidSans-Bold.ttf │ │ │ ├── lib │ │ │ │ ├── jquery.slideto.min.js │ │ │ │ ├── jquery.wiggle.min.js │ │ │ │ ├── highlight.9.1.0.pack_extended.js │ │ │ │ ├── jquery.ba-bbq.min.js │ │ │ │ ├── highlight.9.1.0.pack.js │ │ │ │ ├── swagger-oauth.js │ │ │ │ ├── backbone-min.js │ │ │ │ ├── marked.js │ │ │ │ └── js-yaml.min.js │ │ │ ├── css │ │ │ │ ├── typography.css │ │ │ │ ├── reset.css │ │ │ │ └── style.css │ │ │ ├── o2c.html │ │ │ ├── lang │ │ │ │ ├── translator.js │ │ │ │ ├── zh-cn.js │ │ │ │ ├── ja.js │ │ │ │ ├── tr.js │ │ │ │ ├── pl.js │ │ │ │ ├── pt.js │ │ │ │ ├── en.js │ │ │ │ ├── ru.js │ │ │ │ ├── geo.js │ │ │ │ ├── it.js │ │ │ │ ├── es.js │ │ │ │ └── fr.js │ │ │ └── index.html │ │ ├── sql │ │ │ ├── h2-schema.sql │ │ │ └── postgresql-schema.sql │ │ ├── application.conf │ │ └── logback.xml │ └── scala │ │ ├── persistence │ │ ├── JsonProtocol.scala │ │ ├── entities │ │ │ └── Supplier.scala │ │ └── dal │ │ │ └── SuppliersDal.scala │ │ ├── utils │ │ ├── ActorModule.scala │ │ ├── PersistenceModule.scala │ │ ├── ConfigurationModule.scala │ │ ├── SwaggerDocService.scala │ │ └── CorsSupport.scala │ │ ├── Boot.scala │ │ └── rest │ │ └── SupplierRoutes.scala └── test │ └── scala │ ├── persistence │ └── dal │ │ ├── AbstractPersistenceTest.scala │ │ └── SuppliersDALTest.scala │ └── rest │ ├── AbstractRestTest.scala │ └── RoutesSpec.scala ├── activator.properties ├── .gitignore ├── tutorial └── index.html ├── README.md └── LICENSE /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=0.13.8 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("io.spray" % "sbt-revolver" % "0.7.2") 2 | -------------------------------------------------------------------------------- /src/main/resources/swagger/images/expand.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdiniz/quill-async-akka-http/HEAD/src/main/resources/swagger/images/expand.gif -------------------------------------------------------------------------------- /src/main/resources/swagger/fonts/DroidSans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdiniz/quill-async-akka-http/HEAD/src/main/resources/swagger/fonts/DroidSans.ttf -------------------------------------------------------------------------------- /src/main/resources/swagger/images/collapse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdiniz/quill-async-akka-http/HEAD/src/main/resources/swagger/images/collapse.gif -------------------------------------------------------------------------------- /src/main/resources/swagger/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdiniz/quill-async-akka-http/HEAD/src/main/resources/swagger/images/favicon.ico -------------------------------------------------------------------------------- /src/main/resources/swagger/images/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdiniz/quill-async-akka-http/HEAD/src/main/resources/swagger/images/throbber.gif -------------------------------------------------------------------------------- /src/main/resources/swagger/images/logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdiniz/quill-async-akka-http/HEAD/src/main/resources/swagger/images/logo_small.png -------------------------------------------------------------------------------- /src/main/resources/swagger/images/wordnik_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdiniz/quill-async-akka-http/HEAD/src/main/resources/swagger/images/wordnik_api.png -------------------------------------------------------------------------------- /src/main/resources/swagger/fonts/DroidSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdiniz/quill-async-akka-http/HEAD/src/main/resources/swagger/fonts/DroidSans-Bold.ttf -------------------------------------------------------------------------------- /src/main/resources/swagger/images/explorer_icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdiniz/quill-async-akka-http/HEAD/src/main/resources/swagger/images/explorer_icons.png -------------------------------------------------------------------------------- /src/main/resources/swagger/images/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdiniz/quill-async-akka-http/HEAD/src/main/resources/swagger/images/favicon-16x16.png -------------------------------------------------------------------------------- /src/main/resources/swagger/images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdiniz/quill-async-akka-http/HEAD/src/main/resources/swagger/images/favicon-32x32.png -------------------------------------------------------------------------------- /src/main/resources/swagger/images/pet_store_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdiniz/quill-async-akka-http/HEAD/src/main/resources/swagger/images/pet_store_api.png -------------------------------------------------------------------------------- /src/main/resources/sql/h2-schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS Supplier( 2 | id bigint auto_increment, 3 | name VARCHAR(255), 4 | description VARCHAR(255) 5 | ); 6 | -------------------------------------------------------------------------------- /activator.properties: -------------------------------------------------------------------------------- 1 | name=quill-async-akka-http 2 | title= Quill Async Akka HTTP 3 | description=A starter akka-http and quill async app 4 | tags=quill,akka,scala,async,http,cake 5 | -------------------------------------------------------------------------------- /src/main/resources/sql/postgresql-schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS Supplier( 2 | id VARCHAR(255) PRIMARY KEY NOT NULL, 3 | name VARCHAR(255), 4 | description VARCHAR(255) 5 | ); -------------------------------------------------------------------------------- /src/main/scala/persistence/JsonProtocol.scala: -------------------------------------------------------------------------------- 1 | package persistence 2 | 3 | import persistence.entities.SimpleSupplier 4 | import spray.json.DefaultJsonProtocol 5 | 6 | object JsonProtocol extends DefaultJsonProtocol { 7 | implicit val supplierFormat = jsonFormat2(SimpleSupplier) 8 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.log 3 | 4 | # sbt specific 5 | .cache 6 | .history 7 | .lib/ 8 | .idea/* 9 | dist/* 10 | target/ 11 | lib_managed/ 12 | src_managed/ 13 | project/boot/ 14 | project/plugins/project/ 15 | .DS_Store 16 | # Scala-IDE specific 17 | .scala_dependencies 18 | .worksheet 19 | -------------------------------------------------------------------------------- /src/main/scala/utils/ActorModule.scala: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import akka.actor.ActorSystem 4 | 5 | 6 | trait ActorModule { 7 | val system: ActorSystem 8 | } 9 | 10 | 11 | trait ActorModuleImpl extends ActorModule { 12 | this: Configuration => 13 | val system = ActorSystem("akkingslick", config) 14 | } -------------------------------------------------------------------------------- /src/main/resources/swagger/lib/jquery.slideto.min.js: -------------------------------------------------------------------------------- 1 | (function(b){b.fn.slideto=function(a){a=b.extend({slide_duration:"slow",highlight_duration:3E3,highlight:true,highlight_color:"#FFFF99"},a);return this.each(function(){obj=b(this);b("body").animate({scrollTop:obj.offset().top},a.slide_duration,function(){a.highlight&&b.ui.version&&obj.effect("highlight",{color:a.highlight_color},a.highlight_duration)})})}})(jQuery); 2 | -------------------------------------------------------------------------------- /src/main/scala/persistence/entities/Supplier.scala: -------------------------------------------------------------------------------- 1 | package persistence.entities 2 | 3 | import java.util.UUID 4 | 5 | case class Supplier(id : String, name: String, description: String) { 6 | def toSimpleSupplier = SimpleSupplier(this.name,this.description) 7 | } 8 | 9 | case class SimpleSupplier(name: String, desc: String){ 10 | def toSupplier = Supplier(UUID.randomUUID().toString,this.name,this.desc) 11 | } -------------------------------------------------------------------------------- /src/main/resources/swagger/css/typography.css: -------------------------------------------------------------------------------- 1 | /* Google Font's Droid Sans */ 2 | @font-face { 3 | font-family: 'Droid Sans'; 4 | font-style: normal; 5 | font-weight: 400; 6 | src: local('Droid Sans'), local('DroidSans'), url('../fonts/DroidSans.ttf') format('truetype'); 7 | } 8 | /* Google Font's Droid Sans Bold */ 9 | @font-face { 10 | font-family: 'Droid Sans'; 11 | font-style: normal; 12 | font-weight: 700; 13 | src: local('Droid Sans Bold'), local('DroidSans-Bold'), url('../fonts/DroidSans-Bold.ttf') format('truetype'); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/resources/swagger/o2c.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main/resources/application.conf: -------------------------------------------------------------------------------- 1 | akka { 2 | loglevel = INFO 3 | } 4 | 5 | spray.can.server { 6 | request-timeout = 1s 7 | } 8 | 9 | quilltest { 10 | host=localhost 11 | port=5432 12 | user=postgres 13 | password=postgres 14 | database=quilltest 15 | poolMaxQueueSize=4 16 | poolMaxObjects=4 17 | poolMaxIdle=999999999 18 | poolValidationInterval=100 19 | } 20 | 21 | quill { 22 | host=localhost 23 | port=5432 24 | user=postgres 25 | password=postgres 26 | database=quill 27 | poolMaxQueueSize=4 28 | poolMaxObjects=4 29 | poolMaxIdle=999999999 30 | poolValidationInterval=100 31 | } 32 | -------------------------------------------------------------------------------- /src/main/scala/utils/PersistenceModule.scala: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import io.getquill.{PostgresAsyncContext, SnakeCase} 4 | import persistence.dal.{SuppliersDal, SuppliersDalImpl} 5 | 6 | trait DbContext { 7 | val context : PostgresAsyncContext[SnakeCase] 8 | } 9 | 10 | trait PersistenceModule { 11 | val suppliersDal : SuppliersDal 12 | } 13 | 14 | 15 | trait PersistenceModuleImpl extends PersistenceModule with DbContext{ 16 | this: Configuration => 17 | 18 | override lazy val context = new PostgresAsyncContext[SnakeCase]("quill") 19 | override val suppliersDal = new SuppliersDalImpl(context) 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/test/scala/persistence/dal/AbstractPersistenceTest.scala: -------------------------------------------------------------------------------- 1 | package persistence.dal 2 | 3 | 4 | import io.getquill._ 5 | import utils._ 6 | import org.scalatest.{FunSuite, Suite} 7 | 8 | trait AbstractPersistenceTest extends FunSuite { this: Suite => 9 | 10 | trait Modules extends ConfigurationModuleImpl with PersistenceModuleTest { 11 | } 12 | 13 | 14 | trait PersistenceModuleTest extends PersistenceModule with DbContext{ 15 | this: Configuration => 16 | override lazy val context = new PostgresAsyncContext[SnakeCase]("quilltest") 17 | override val suppliersDal: SuppliersDal = new SuppliersDalImpl(context) 18 | val self = this 19 | 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /src/main/scala/utils/ConfigurationModule.scala: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import java.io.File 4 | 5 | import com.typesafe.config.{Config, ConfigFactory} 6 | 7 | trait Configuration { 8 | def config: Config 9 | } 10 | 11 | trait ConfigurationModuleImpl extends Configuration { 12 | private val internalConfig: Config = { 13 | val configDefaults = ConfigFactory.load(this.getClass().getClassLoader(), "application.conf") 14 | 15 | scala.sys.props.get("application.config") match { 16 | case Some(filename) => ConfigFactory.parseFile(new File(filename)).withFallback(configDefaults) 17 | case None => configDefaults 18 | } 19 | } 20 | 21 | def config = internalConfig 22 | } -------------------------------------------------------------------------------- /src/main/resources/swagger/lib/jquery.wiggle.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | jQuery Wiggle 3 | Author: WonderGroup, Jordan Thomas 4 | URL: http://labs.wondergroup.com/demos/mini-ui/index.html 5 | License: MIT (http://en.wikipedia.org/wiki/MIT_License) 6 | */ 7 | jQuery.fn.wiggle=function(o){var d={speed:50,wiggles:3,travel:5,callback:null};var o=jQuery.extend(d,o);return this.each(function(){var cache=this;var wrap=jQuery(this).wrap('
').css("position","relative");var calls=0;for(i=1;i<=o.wiggles;i++){jQuery(this).animate({left:"-="+o.travel},o.speed).animate({left:"+="+o.travel*2},o.speed*2).animate({left:"-="+o.travel},o.speed,function(){calls++;if(jQuery(cache).parent().hasClass('wiggle-wrap')){jQuery(cache).parent().replaceWith(cache);} 8 | if(calls==o.wiggles&&jQuery.isFunction(o.callback)){o.callback();}});}});}; -------------------------------------------------------------------------------- /src/main/scala/Boot.scala: -------------------------------------------------------------------------------- 1 | import akka.http.scaladsl.Http 2 | import akka.http.scaladsl.server.RouteConcatenation 3 | import akka.stream.ActorMaterializer 4 | import rest.SupplierRoutes 5 | import utils._ 6 | 7 | object Main extends App with RouteConcatenation with CorsSupport{ 8 | // configuring modules for application, cake pattern for DI 9 | val modules = new ConfigurationModuleImpl with ActorModuleImpl with PersistenceModuleImpl 10 | implicit val system = modules.system 11 | implicit val materializer = ActorMaterializer() 12 | implicit val ec = modules.system.dispatcher 13 | 14 | val swaggerService = new SwaggerDocService(system) 15 | 16 | val bindingFuture = Http().bindAndHandle( 17 | new SupplierRoutes(modules).routes ~ 18 | swaggerService.assets ~ 19 | corsHandler(swaggerService.routes), "localhost", 8080) 20 | 21 | println(s"Server online at http://localhost:8080/") 22 | 23 | } -------------------------------------------------------------------------------- /src/test/scala/rest/AbstractRestTest.scala: -------------------------------------------------------------------------------- 1 | package rest 2 | 3 | import org.scalatest.{Matchers, WordSpec} 4 | import org.specs2.mock.Mockito 5 | import persistence.dal.{SuppliersDal, SuppliersDalImpl} 6 | import utils.{ActorModule, ConfigurationModuleImpl, DbContext, PersistenceModule} 7 | import com.typesafe.config.Config 8 | import com.typesafe.config.ConfigFactory 9 | import akka.http.scaladsl.testkit.ScalatestRouteTest 10 | import io.getquill._ 11 | trait AbstractRestTest extends WordSpec with Matchers with ScalatestRouteTest with Mockito{ 12 | 13 | trait Modules extends ConfigurationModuleImpl with ActorModule with PersistenceModule with DbContext { 14 | val system = AbstractRestTest.this.system 15 | 16 | override lazy val context = ??? 17 | override val suppliersDal: SuppliersDal = mock[SuppliersDal] 18 | 19 | } 20 | 21 | def getConfig: Config = ConfigFactory.empty(); 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/scala/utils/SwaggerDocService.scala: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import scala.reflect.runtime.{universe => ru} 4 | import akka.actor.ActorSystem 5 | import akka.http.scaladsl.model.StatusCodes 6 | import akka.stream.ActorMaterializer 7 | import com.github.swagger.akka._ 8 | import com.github.swagger.akka.model.Info 9 | import rest.SupplierRoutes 10 | 11 | class SwaggerDocService(system: ActorSystem) extends SwaggerHttpService with HasActorSystem { 12 | override implicit val actorSystem: ActorSystem = system 13 | override implicit val materializer: ActorMaterializer = ActorMaterializer() 14 | override val apiTypes = Seq(ru.typeOf[SupplierRoutes]) 15 | override val host = "localhost:8080" 16 | override val info = Info(version = "2.0") 17 | 18 | def assets = pathPrefix("swagger") { 19 | getFromResourceDirectory("swagger") ~ pathSingleSlash(get(redirect("index.html", StatusCodes.PermanentRedirect))) } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 |The Quill Async Akka Http is a very simple json rest api showing one way of using akka http with quill using postgres async. 11 |
12 | 13 |It supports the following features:
14 | 15 |Utils: Typesafe config for property management and Typesafe Scala Logging (LazyLogging)
24 |Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.', 51 | 'Learn how to use', 52 | '
', 53 | '' + appName + ' API requires the following scopes. Select which ones you want to grant to Swagger UI.
', 54 | '