wip, may be, never publish

This commit is contained in:
Yann Esposito (Yogsototh) 2021-11-02 16:07:51 +01:00
parent 96646455bd
commit 9dcedab3aa
Signed by untrusted user who does not match committer: yogsototh
GPG Key ID: 7B19A4C650D59646
1 changed files with 99 additions and 1 deletions

View File

@ -39,10 +39,108 @@ What provide a good algebraic abstraction is the certainty that your system
will be *composable* upon some properties.
So the important word here is *composability* which is arguably superior to /modularity/.
Modularity is about combining different systems.
Here are a few example about how far we could / should go.
[fn:simple-vs-easy] If you want a great overview of the subject, I highly
suggest you to watch [[https://thestrangeloop.com/2011/simple-made-easy.html][Simple made Easy]] video from Rich Hickey.
[fn:einstein] This is only attributed to Albert Einstein. He apparently
said something similar but we don't have any strong evidence he wrote or
said exactly that.
* CRUD+Search
:PROPERTIES:
:CUSTOM_ID: crud-search
:END:
With this simple abstraction you could build successful API.
#+begin_src clojure
(defprotocol CRUDPS
(create [this id value])
(read [this id])
(update [this id new-value])
(delete [this id])
(patch [this id new-partial-value])
(search [this partial-value pagination-parameters]))
#+end_src
One important detail is that we could provide "partial values".
So we should have a language that should support the notion of "sub-object".
And if you are doing this in javascript, this should be easy.
In Java or Haskell, it might be a bit more funky.
So just that. It is even simpler than an ORM.
You don't need more than that most of the time.
If you force yourself to work within this restriction this give you
immediately a few pretty good properties.
1. *Portability*; This protocol is so simple to write it is easy to implement
it for different DBs. Postgres, ES, MongoDB, etc...
2. *Scalability*; as this only focus on a single table/index, you do not have
to think about join.
One of the most important property of my system is generally to never
write join.
And you can go surprisingly far without the need of any join.
In fact, most of the time "fake join" are more efficient, et good enough
for almost all user facing use case.
3. *Simplicity*; by only using this API internally, it is easy to manipulate
DB accesses.
Use HTTP, with 90% CRUD + Search.
This is enough for most use cases.
And by search, don't think about something too fancy.
A sub-JSON will be enough for most use case.
Then later you will probably want to add text search/matching.
Why sub-JSON is probably superior to your SQL query?
Because it is composable, more precisely this is a morphism, which SQL
queries aren't.
What do I precisely mean by "sub-JSON"?
Simply the ~<@~ operator in Postgres.
Or the basic MongoDB/ES search.
Not some system introducing complex structure.
So you want to match:
#+begin_src js
{"foo":"bar"}
// should match with
{"foo": bar,
"x": "y"}
// but shouldn't match
{"foo":"notbar",
"x":"y"}
//nor
{"x":"y"}
#+end_src
So this is a morphism with the following property:
#+begin_src
(find x) AND (find y) <=> (find (x inter y))
#+end_src
Which is not possible to easily do with a SQL query.
If you have a string representing a query Q1, and another string
representing a query Q2.
It is difficult to produce a query for Q1 AND Q2.
Because, there are field selection for example.
For most modern web application/API you don't need to enforce strong
constant on that either.
For example, you can loose so much time trying to support a great update or patch.
Doing so in a concurrent system is hard.
If you don't care much, most of the time this will be perfectly ok.
So just with that and the correct data structure.
No search by text, no join.
Just 1 table, per data structure saving JSON + the ability to search by sub-json.
We created, multiple time, a big reliable and nice to use API.
No surprise, no discussion about query optimization, no problem about scalability.