Skip to content

Instantly share code, notes, and snippets.

@BalmungSan
Created January 13, 2020 22:01
Show Gist options
  • Save BalmungSan/d0e0b9ba9782f9363ae941743ab124a7 to your computer and use it in GitHub Desktop.
Save BalmungSan/d0e0b9ba9782f9363ae941743ab124a7 to your computer and use it in GitHub Desktop.
Neotypes demo for ScalaMDE 2019
/** 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