Now you should use play-autosource 2.0 correcting a few issues & introducing ActionBuilder from play2.2
The code for all autosources & sample apps can be found on Github here
Brand New Autosources
Play AutoSource now have 2 more implementations :- Datomic based on Datomisca, the Scala API I developed with Daniel James (@dwhjames) sponsored by Pellucid Analytics & Zenexity which is presented in this article
- CouchBase contributed by Mathieu Ancelin @TrevorReznik
- Slick/JDBC based on Play2-Slick contributed by Renato Cavalcanti and Loic Descotte
One month ago, I’ve demo’ed the concept of Autosource for Play2/Scala with ReactiveMongo in this article. ReactiveMongo was the perfect target for this idea because it accepts Json structures almost natively for both documents manipulation and queries.
But how does the concept behave when applied on a DB for which data are constrained by a schema and for which queries aren’t Json.
Using Datomisca-Autosource in your Play project
Add following lines to your project/Build.scala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Create your Model + Schema
With ReactiveMongo Autosource, you could create a pure blob Autosource using JsObject
without any supplementary information. But with Datomic, it’s not possible because Datomic forces to use a schema for your data.
We could create a schema and manipulate JsObject
directly with Datomic and some Json validators. But I’m going to focus on the static models because this is the way people traditionally interact with a Schema-constrained DB.
Let’s create our model and schema.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Create Datomisca Autosource
Now that we have our schema, let’s write the autosource.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
Implementing Json <-> Person <-> Datomic transformers
If you compile previous code, you should have following error:
1
|
|
Actually, Datomisca Autosource requires 4 elements to work:
Json.Format[Person]
to convertPerson
instances from/to Json (network interface)EntityReader[Person]
to convertPerson
instances from Datomic entities (Datomic interface)PartialAddEntityWriter[Person]
to convertPerson
instances to Datomic entities (Datomic interface)Reads[PartialAddEntity]
to convert Json toPartialAddEntity
which is actually a simple map of fields/values to partially update an existing entity (one single field for ex).
It might seem more complicated than in ReactiveMongo but there is nothing different. The autosource converts Person
from/to Json and then converts Person
from/to Datomic structure ie PartialAddEntity
. In ReactiveMongo, the only difference is that it understands Json so well that static model becomes unnecessary sometimes ;)…
Let’s define those elements in Person
companion object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
Now we have everything to work except a few configurations.
Add AutoSource routes at beginning conf/routes
1
|
|
Create conf/play.plugins
to initialize Datomisca Plugin
1
|
|
Append to conf/application.conf
to initialize MongoDB connection
1
|
|
Insert your first 2 persons with Curl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Querying is the biggest difference in Datomic
In Datomic, you can’t do a getAll
without providing a Datomic Query.
But what is a Datomic query? It’s inspired by Datalog
which uses predicates to express the constraints on the searched entities. You can combine predicates together.
With Datomisca Autosource, you can directly send datalog queries in the query parameter q
for GET or in body for POST with one restriction: your query can’t accept input parameters and must return only the entity ID. For ex:
[ :find ?e :where [ ?e :person/name "john"] ] --> OK
[ :find ?e ?name :where [ ?e :person/name ?name] ] --> KO
Let’s use it by finding all persons.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Please note the use of POST here instead of GET because Curl doesn’t like
[]
in URL even using-g
option
Now you can use all other routes provided by Autosource
Autosource Standard Routes
Get / Find / Stream
- GET /persons?… -> Find by query
- GET /persons/ID -> Find by ID
- GET /persons/stream -> Find by query & stream result by page
Insert / Batch / Find
- POST /persons + BODY -> Insert
- POST /persons/find + BODY -> find by query (when query is too complex to be in a GET)
- POST /persons/batch + BODY -> batch insert (multiple)
Update / batch
- PUT /persons/ID + BODY -> Update by ID
- PUT /persons/ID/partial + BODY -> Update partially by ID
- PUT /persons/batch -> batch update (multiple)
Delete / Batch
- DELETE /persons/ID -> delete by ID
- DELETE /persons/batch + BODY -> batch delete (multiple)
Conclusion
Play-Autosource’s ambition was to be DB agnostic (as much as possible) and showing that the concept can be applied to schemaless DB (ReactiveMongo & CouchDB) and schema DB (Datomic) is a good sign it can work. Naturally, there are a few more elements to provide for Datomic than in ReactiveMongo but it’s useful anyway.
Thank to @TrevorReznik for his contribution of CouchBase Autosource.
I hope to see soon one for Slick and a few more ;)
Have Autofun!