Skip to content

Instantly share code, notes, and snippets.

@fedesilva
Last active January 30, 2018 22:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fedesilva/dfe041ff7d029c43cd232717c324daa7 to your computer and use it in GitHub Desktop.
Save fedesilva/dfe041ff7d029c43cd232717c324daa7 to your computer and use it in GitHub Desktop.
Very basic type class example.
//
// While testing the Elasticsearch 6.x http client works for me, using circe for json,
// I added a silly `Entity` type class which describes how to get an ID from an entity.
//
import java.util.UUID
import org.apache.http.HttpHost
import org.elasticsearch.action.index.IndexRequest
import org.elasticsearch.client.{RestClient, RestHighLevelClient}
import org.elasticsearch.common.xcontent.XContentType
import io.circe._
import generic.auto._
import syntax._
// Type class that allows treating a type as an entity; that is, an object that is identified by
// its `primary key` in storage, as opposed to a value object where the identity is determined by it's
// member values.
trait Entity[T] {
def id(i: T): String
}
// Companion object defines the "interface".
object Entity {
def id[T](i: T)(implicit tc: Entity[T]): String = tc.id(i)
}
// A Data Type
case class Project(id: String, name: String)
// And an Entity instance for that type.
// Note I don't create an anonymous class because single method traits can be treated as
// functions.
implicit val entityProject: Entity[Project] = (i: Project) => i.id
//
// Create an elasticsearch client
//
val client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")
)
)
// Helper
def buildProject(name: String): Project = {
val id = UUID.nameUUIDFromBytes(name.getBytes).toString
Project( id, name )
}
// This function is generic in the type of what it indexes, but it requires that there are instances for
// Encoder (circe json encoder) and Entity (se we can get to the id)
def buildIndexRequest[T : Encoder : Entity](doc: T): IndexRequest = {
new IndexRequest(
"posts",
"doc",
Entity.id(doc)
).source(doc.asJson.toString(), XContentType.JSON)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment