Last active
January 30, 2018 22:14
-
-
Save fedesilva/dfe041ff7d029c43cd232717c324daa7 to your computer and use it in GitHub Desktop.
Very basic type class example.
This file contains 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
// | |
// 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