Created
January 13, 2020 22:01
-
-
Save BalmungSan/d0e0b9ba9782f9363ae941743ab124a7 to your computer and use it in GitHub Desktop.
Neotypes demo for ScalaMDE 2019
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Neotypes demo for ScalaMDE 2019. */ | |
// Imports. | |
// // FS2. | |
import fs2.Stream | |
// // Neotypes. | |
import neotypes.{GraphDatabase, Session} | |
import neotypes.implicits.all._ | |
import neotypes.cats.effect.implicits._ | |
import neotypes.fs2.implicits._ | |
// // HTTP4S. | |
import org.http4s.HttpRoutes | |
import org.http4s.dsl.Http4sDsl | |
import org.http4s.server.Router | |
import org.http4s.server.blaze.BlazeServerBuilder | |
import org.http4s.syntax.kleisli._ | |
// // Cats-Effect. | |
import cats.effect.{ExitCode, IO, IOApp, Resource} | |
// Main. | |
object Main extends IOApp { | |
final val program = Stream.resource(Neo4j.instance).flatMap { neo4j => | |
BlazeServerBuilder[IO] | |
.bindHttp(port = 8080, host = "localhost") | |
.enableHttp2(true) | |
.withoutBanner | |
.withHttpApp( | |
Router( | |
"/" -> Services.peopleService(neo4j) | |
).orNotFound | |
).serve | |
} | |
override def run(args: List[String]): IO[ExitCode] = | |
program.compile.lastOrError | |
} | |
// Services. | |
object Services extends Http4sDsl[IO] { | |
def peopleService(neo4j: Neo4j): HttpRoutes[IO] = HttpRoutes.of[IO] { | |
case GET -> Root / "person" / person / "friends" => | |
Ok( | |
neo4j | |
.getFriendsOf(personName = person) | |
.map(friends => friends.mkString("\n")) | |
) | |
case GET -> Root / "people" => | |
Ok(neo4j.getAllPeople.intersperse("\n")) | |
} | |
} | |
// Persistence. | |
object Neo4j { | |
final val instance: Resource[IO, Neo4j] = | |
for { | |
driver <- GraphDatabase.driver[IO]("bolt://localhost:7687") | |
session <- driver.session | |
} yield new Neo4j(session) | |
} | |
final class Neo4j private (private[this] val session: Session[IO]) { | |
def getFriendsOf(personName: String): IO[Set[String]] = | |
session.transaction.use { tx => | |
c"""MATCH (: Person { name: ${personName}})-[:FRIENDS_WITH]-(friend: Person) | |
RETURN DISTINCT friend.name""".query[String].set(tx) | |
} | |
def getAllPeople: Stream[IO, String] = | |
Stream.resource(session.transaction).flatMap { tx => | |
c"""MATCH (person: Person) | |
RETURN DISTINCT person.name""".query[String].stream[Stream[IO, ?]](tx) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment