- Une plateforme banking-as-a-service qui permet aux fintechs de connecter directement ouverture de compte, paiements et onboarding comme via une API bancaire ; en mars 2023, elle a obtenu une licence bancaire britannique et est devenue une banque réglementée
- Le système fonctionne sur Clojure on Kubernetes on AWS, avec une architecture d’event sourcing qui transforme la plupart des entrées en événements, combinée au stockage FoundationDB
- FoundationDB est un key-value store strict-serializable qui prend en charge les transactions et les écritures concurrentes ; Griffin construit des lectures/écritures atomiques via une couche de type Datomic issue du portage de Datascript
- La logique métier est isolée autour de petits log processors qui prennent une map Clojure en entrée et produisent une map Clojure en sortie ; l’accès aux systèmes externes est limité par des protocoles et des proc dédiés
- L’immutabilité de Clojure et son adéquation avec les journaux d’audit répondent bien aux exigences des services financiers ; combiné au recrutement à distance, cela faciliterait la recherche d’ingénieurs de grande qualité même dans un vivier restreint
Une plateforme bancaire réglementée fournie sous forme d’API
- Griffin est une plateforme de banking-as-a-service qui aide les fintechs à intégrer rapidement et en toute sécurité des fonctionnalités bancaires
- En mars 2023, elle a obtenu une UK banking license auprès de la Financial Conduct Authority, devenant ainsi une banque britannique entièrement réglementée
- Griffin se présente comme “the bank you can build on” et vise à être une infrastructure comparable à AWS pour la banque
- API d’onboarding client
- API de création de comptes bancaires
- API de paiement
- Pour proposer ce type de fonctionnalités, les fintechs doivent légalement collaborer avec une banque ; aujourd’hui, cela se fait souvent avec des high street banks historiques utilisant des mainframes
- Griffin veut fournir à la fois une licence bancaire et une plateforme technologique, afin de devenir une base sur laquelle les fintechs de demain pourront construire leurs services
- La licence avait été obtenue, mais Griffin se trouvait alors en phase de mobilization ; cette phase devait prendre fin après l’achèvement de l’audit, une levée de fonds supplémentaire et la finalisation du code
- L’objectif était le T3 ou le T4 de cette année-là
Pourquoi Clojure a été choisi
- Clojure a été choisi comme langage de la plateforme pour son immutabilité, son expressivité et son adéquation avec les services financiers nécessitant des journaux d’audit
- Allen Rohner a vu une présentation de Clojure par Rich Hickey vers 2007 et a jugé que c’était meilleur que le Lisp qu’il était en train de créer
- Après avoir fondé CircleCI en 2011, il a utilisé Clojure pendant longtemps ; cela a bien fonctionné chez CircleCI et lui a paru également adapté aux services financiers
- Concernant la JVM, il n’en a pas pleinement perçu les avantages pendant les premières années, mais son opinion a ensuite évolué pour y voir un atout majeur
- D’autres niche startup languages peuvent souffrir d’un manque de bibliothèques ou de problèmes de performances du compilateur et du runtime
- La JVM constitue une base qui réduit ces risques
- Le choix d’un langage révèle la nature d’une entreprise, et Clojure a été considéré comme un choix plus fort que Python ou Java
- Utiliser un niche language réduit le nombre de candidats, mais peut augmenter la proportion de talents seniors
Une couche de données construite avec FoundationDB
- L’architecture de Griffin fonctionne sur Clojure, Kubernetes et AWS, et repose presque entièrement sur l’event sourcing
- La base de données utilisée est FoundationDB
- FoundationDB est un key-value store strict-serializable prenant en charge les transactions
- À l’origine, c’était une startup de la Silicon Valley
- Elle a été acquise par Apple en 2015
- Vers 2018, Apple l’a republiée en open source
- Apple l’utilise en production pour iCloud
- Apple a réalisé des benchmarks montrant FoundationDB fonctionnant à environ 1 million de transactions par seconde
- Le strict serializable correspond au niveau le plus élevé de cohérence d’une base de données
- L’API de base ressemble à
get a key,set a key, et non à SQL - Griffin a porté Datascript sur FoundationDB pour construire une couche de type Datomic
- Elle permet des requêtes atomiques au-dessus d’un stockage strict-serializable
- Elle prend en charge les lectures et écritures transactionnelles
- FoundationDB n’est pas un système à single writer : il prend en charge les écritures concurrentes
- Griffin a besoin de plus de 1 000 transactions par seconde, et cette exigence est satisfaite
Event sourcing et log processors
- Toutes les entrées du système Griffin deviennent des événements
- API request
- webhook tiers
- Les événements sont placés dans un message log ; chez Griffin, un événement est une map Clojure contenant un champ
type, des key/value et une spec - L’ensemble du système est structuré comme une réaction à ces événements
- Les petits log processors sont appelés
proc- Un proc fonctionne selon un modèle du type : “écouter le message type A et, en réaction, émettre B ou C”
- Chaque proc possède son propre état privé
- Le flux de messages peut être représenté sous forme de graphe, et les événements se déplacent jusqu’à atteindre un nœud terminal
- Par exemple, le serveur web reçoit un événement HTTP, enregistre une demande de paiement, puis attend un événement
payment createdoupayment rejectedavant de répondre au client- Ce flux utilise un Netty asynchronous HTTP handler
- Tous les événements sont enregistrés dans FoundationDB
- Chaque log processor possède dans FoundationDB des données privées, comparables à son propre namespace
- Le proc surveille l’enregistrement de certains types d’événements, puis enregistre à son tour ses propres événements dans FoundationDB
- FoundationDB fournit une fonction de surveillance des changements de clés en base, ce qui permet de créer efficacement un système réactif
- Utiliser une base de données et un système de messagerie séparé peut créer des race conditions
- Par exemple, si un message part vers le disque et un autre vers le réseau, un observateur peut les voir dans un ordre différent
- Griffin utilise l’écriture dans FoundationDB afin de simplifier le système autour d’un chemin unique
Monorepo et isolation de la logique métier
- Griffin utilise un monorepo
- Aujourd’hui, pour des raisons d’efficacité, de nombreux log processes s’exécutent dans la même JVM
- Chacun est indépendant et pourrait aussi être exécuté comme un process JVM séparé
- Actuellement, un nombre de proc de l’ordre de quelques centaines s’exécutent dans une seule JVM
- La logique métier est maintenue aussi simple et propre que possible
- Les namespaces de chaque log processor sont presque entièrement du Clojure pur
- Il y a très peu de bibliothèques tierces
- Les effets de bord sont également très limités
- Un log processor ressemble à une fonction qui prend une map Clojure en entrée et renvoie une ou plusieurs maps Clojure
- L’état d’un proc expose un protocol, ce qui évite de connaître l’implémentation située de l’autre côté
- En test, il peut utiliser une base de données en mémoire
- En production, il peut écrire dans FoundationDB
- Les interfaces avec le monde extérieur sont maintenues aussi petites que possible
- La plupart des proc peuvent seulement écrire dans leur état interne et émettre des messages
- Pas d’appel réseau
- Pas d’appel AWS
- Aucun autre effet externe
- Lorsqu’il faut communiquer avec un système externe, un proc spécial doté d’un dispatch handler dédié est utilisé
- Proc communiquant avec AWS
- Proc communiquant avec une clearing bank
- Proc communiquant avec une autre API
L’écosystème Clojure utilisé
- À l’intérieur de la logique métier, très peu de bibliothèques sont utilisées
- Dans les zones en contact avec le monde extérieur, comme l’API web server ou le service gateway, Griffin utilise :
ringnettyreitit
- Clojure spec est utilisé de façon extensive
- Pour l’intégration AWS, la bibliothèque Cognitect
aws-apiest utilisée - Pour la configuration applicative et la gestion des ressources, Griffin utilise une approche fondée sur l’article de blog closeable
- L’idée est que
with-opensuffit, sans Component ni Integrant - Cela permet d’obtenir une portée lexicale, et l’ordre de déclaration des bindings impose l’ordre de configuration
- Un petit helper est utilisé pour déclarer dans un bloc
with-opendes objets d’état qui n’implémentent pasCloseable, ou des objets stateless
- L’idée est que
Recrutement et composition de l’équipe
- Griffin estime que le recrutement Clojure attire moins de candidats, mais une proportion plus élevée de bons profils
- En Java, 1 000 CV peuvent ne produire que 10 bons candidats
- En Clojure, 13 CV peuvent produire 10 bons candidats, selon la formulation utilisée
- Dans un petit vivier de recrutement, le travail à distance est important
- En réduisant les contraintes géographiques, on peut constituer un vivier plus large : mondial, dans un périmètre de trois fuseaux horaires, européen, etc.
- Devoir recruter 100 ingénieurs en peu de temps est considéré comme un anti-pattern
- L’entreprise compte environ 70 personnes au total
- L’engineering compte environ 22 à 24 personnes
- Environ deux tiers sont au Royaume-Uni
- Environ un tiers est dans l’UE
- L’équipe comprend environ 4 personnes en Allemagne, 4 en Suède et 1 en Irlande
- Le siège est à Londres, mais la plupart des développeurs britanniques sont en dehors de Londres
Tests de résilience opérationnelle au niveau bancaire
- En tant que banque, Griffin doit être operationally resilient, ce qui correspond presque à une exigence d’absence de downtime
- Comme l’entreprise manipule de l’argent, elle doit prouver concrètement qu’un problème ne fera pas perdre l’argent des clients
- La direction de test qui l’intéresse ressemble à l’approche de l’équipe FoundationDB
- L’équipe FoundationDB a construit un simulateur de base de données
- Environ 20 process types, c’est-à-dire les rôles internes du cluster, ont été écrits sous forme d’application C++ single-threaded
- Un compilateur de concurrence de type actor model a été construit au-dessus de C++
- Tous les system calls et network calls passent par des protocoles afin de permettre l’injection d’erreurs
- Le multi-threading est également traité via un actor model fondé sur l’envoi de messages
- Dans cet environnement, il est possible d’injecter des erreurs de façon déterministe
- Cas où les messages A et B sont envoyés, mais arrivent de l’autre côté dans l’ordre B, A
- Cas où une erreur d’écriture disque se produit pendant le traitement d’un message
- Cela ressemble au generative testing de
test.check, dans le sens où toute la non-détermination du système est seedée depuis un seul random number contrôlable - Les éléments que Griffin veut contrôler sont les disk errors, network errors et message reordering
- Le problème actuel est qu’il n’existe pas de moyen de contrôler le comportement des Java threading libraries, de NIO et des écritures disque
- L’approche partage l’esprit de Jepsen, mais avec des différences
- Jepsen est perçu comme une méthode plus brute force, avec plusieurs VM et des processus que l’on tue
- Il est difficile d’inspecter l’état interne de la base de données, donc de connaître la couverture
- Dans un environnement entièrement contrôlable, on peut énumérer les system calls ou les interleavings de messages, et comme tout est en mémoire, les vérifications sont très rapides
- L’équipe FoundationDB a construit ce type d’environnement de test très tôt, ce qui contribue à la confiance accordée à FoundationDB
- Griffin recrute, et des informations sont disponibles sur la page carrières de Griffin
1 commentaires
Avis sur Hacker News
James Trunk, actuel VP of Engineering de Griffin, a donné la présentation d’introduction technique à Clojure la plus claire et la plus amusante que j’aie vue. Je la recommande
https://youtu.be/C-kF25fWTO8?si=PnjMNLdBLJ8zqSu-
Le problème aujourd’hui, c’est qu’il n’y a aucun moyen de contrôler les bibliothèques de threading Java sous-jacentes, NIO ni le comportement des écritures disque, et vu la nature de ce type de système, il me semble que ce ne sera pas possible non plus à l’avenir
On ne peut pas obtenir une exécution déterministe dans un système qui utilise un ordre de requêtes ou une planification des tâches non déterministes. C’est ce qui se produit dès qu’on utilise en permanence plusieurs threads d’OS, ou qu’on lance plusieurs processus distincts dans les tests
On pourrait le rendre déterministe de force, mais ce serait très difficile, car il faudrait insérer des points de synchronisation contrôlables par les tests dans chaque transition de la machine à états applicative
En pratique, il me semble que la seule solution est de concevoir le cœur du système de manière entièrement synchrone, puis d’ajouter la concurrence à un niveau supérieur au moment de l’exécution
procsn’ont pas d’effets de bord, sauf ce qui se passe derrière les protocoles Clojure (interfaces Java)On peut donc remplacer tous les effets de bord par des stubs pendant les tests. Notre code « utilisateur » n’a pas accès aux bibliothèques de threading, et le threading se produit dans le code « noyau »
On peut voir un bon exemple déjà implémenté de cette approche ici : https://www.youtube.com/watch?v=4fFDFbi3toc
missionary instrumente déjà ses flux et vérifie les transitions d’état pour ses propres tests
C’est assez chouette que les deux fondateurs aient coécrit un livre intitulé Learning ClojureScript
https://www.packtpub.com/product/learning-clojurescript/9781...
La phrase « Nous plaisantons souvent en disant que nous sommes une entreprise tech avec une licence bancaire » est le genre de citation qui pourrait très mal passer plus tard si les choses tournaient mal
Mon employeur se présentait comme une entreprise de recherche éducative qui commercialise les résultats de la recherche grâce au logiciel, et cela me paraissait beaucoup plus convaincant, tout en créant une meilleure culture
Dans la banque, le coût de réapprentissage de ce savoir peut être très élevé
Question sincère, et désolé pour la formulation abrupte, mais pourquoi devrais-je me soucier du langage dans lequel est écrit un service que j’utilise ? Pourquoi est-ce important qu’il soit écrit en Clojure ? Professionnellement, je suis développeur Clojure, donc c’est sympa de voir ce genre de chose écrit en Clojure, mais je ne comprends pas pourquoi je devrais m’en soucier
C’est l’un des aspects de la communauté que je déteste vraiment. Clojure est un langage puissant et j’aime l’utiliser, mais j’ai l’impression qu’il y a dans la communauté une sorte de syndrome de l’imposteur, comme s’il fallait dire aux autres qu’on utilise ce langage dans un projet et le justifier, ce que je trouve étrange
Je ne vois pas bien où est le problème. Ce serait un comportement inapproprié dans une société civilisée ?
Ça sonne assez ignorant. Si ça ne t’« intéresse pas », tu n’es pas obligé de t’en mêler, et tu peux laisser l’auteur écrire ce qu’il veut écrire
Je me souviens que dans les années 90, des développeurs PHP et Python partageaient ce genre d’exemples pour répondre à des questions business du type « pourquoi ne pas utiliser Microsoft ASP »
Ou bien il s’agit peut-être d’attirer des développeurs dans leur propre entreprise
Pourquoi ces banques API sont-elles toujours au Royaume-Uni ? Ça fait des années que j’ai envie de faire des opérations bancaires avec curl, mais personne ne le propose aux États-Unis
À l’inverse, le Royaume-Uni a activement encouragé les nouvelles banques et les nouvelles technologies. Les virements instantanés et gratuits entre comptes personnels existent depuis près de 20 ans, les paiements sans contact depuis au moins 10 ans, la banque mobile depuis des décennies, et les API bancaires imposées par l’État depuis près de 5 ans
En bref, le Royaume-Uni dispose d’un secteur bancaire très dynamique, qui a innové rapidement selon les critères bancaires, et d’un environnement et d’un écosystème bien développés pour accélérer encore l’innovation
Aux États-Unis, les banques semblent avoir abandonné l’innovation technologique il y a des décennies, préférant innover dans les frais et le traitement punitif des clients. Il n’y a donc pas de nouvel environnement d’innovation, et il est beaucoup plus facile pour les banques en place d’écraser les concurrents plutôt que de rivaliser avec eux
Jusqu’à récemment, le Royaume-Uni comptait lui aussi étonnamment peu de banques indépendantes ; si la même chose ne s’y est pas produite, c’est probablement en raison de la nature des lois et de la réglementation, qui garantissent de nombreux droits aux clients et sanctionnent activement les banques qui ne les respectent pas
Aux États-Unis, les banques qui disposent d’API ont tendance à se concentrer sur de gros partenariats fintech ; même une API simple coûtera donc cher par rapport à un compte bancaire ordinaire. Par exemple, Grasshopper Bank aux États-Unis fait partie des rares banques à proposer une API au-dessus d’un compte bancaire commercial classique
Je travaille chez Treasury Prime, qui prend en charge plusieurs banques américaines proposant des API
Côté comptes personnels, Monzo et Starling sont les plus connues des banques dites challenger[1]
[1]: https://en.wikipedia.org/wiki/Challenger_bank
Column – une banque agréée pour les développeurs
https://news.ycombinator.com/item?id=31109170
« Il reste une technologie propriétaire supplémentaire que nous devons publier en open source. Nous avons porté Datascript sur FoundationDB » : pitié, qu’ils la publient
Je suis curieux de voir comment cela fonctionnerait comme alternative à Datomic
La phrase « légalement, pour faire ce genre de choses, les fintechs doivent travailler avec une banque, ce qui aujourd’hui signifie une grande banque traditionnelle utilisant des mainframes. Griffin est la banque et la plateforme technologique sur lesquelles toutes les fintechs du futur s’appuieront » donne l’impression d’avoir été écrite en 2016
Le marché a déjà avancé. Griffin a l’air bien, mais ils ont plusieurs années de retard sur beaucoup d’acteurs, et des entreprises établies comme ClearBank proposent déjà de bonnes API bancaires
Il y a de la place pour davantage d’acteurs, donc l’arrivée de Griffin sur le marché est bienvenue, mais j’aimerais que le pitch ne soit pas aussi faible
Et une bonne API ne suffit pas. Il faut tout un modèle opérationnel adapté à sa clientèle, et c’est bien plus difficile à construire
Pas encore. Il est écrit : « une fois que nous aurons terminé l’audit, levé davantage de fonds et fini d’écrire le code, nous retirerons les petites roues. Ce sera vers le troisième ou le quatrième trimestre de cette année »
Je déteste vraiment quand un article commence par « dans une startup, il faut utiliser le langage le plus puissant disponible, et c’est Clojure »
Ce n’est que votre opinion. Dans une startup, il faut utiliser le langage qui permet à l’équipe de construire et lancer un MVP le plus vite possible afin d’obtenir les premiers clients ou investissements. Pour une startup ordinaire, cela pourrait même être une plateforme low-code ou no-code, même si c’est probablement moins le cas en fintech
À la rigueur, on pourrait aussi dire que Python est le langage le plus puissant à cause des LLM et du machine learning, et je suis pourtant habituellement développeur PHP. Python pourrait devenir encore plus puissant grâce à Mojo, qui est censé rendre Python 36 000 fois plus rapide
Mais je ne dirais jamais qu’un langage X est le seul et le plus puissant langage à utiliser dans une startup. C’est totalement faux, et ce n’est qu’une opinion
Par exemple, selon moi, je suis d’accord avec cette opinion :-) Mon activité solo n’aurait pas été possible sans Clojure et ClojureScript, et cela montre la « puissance » de ce langage
Je considère ce langage comme « puissant » parce qu’il permet à un seul développeur d’écrire et de maintenir des applications complexes pendant des années. Il me donne du pouvoir
Clojure a une communauté assez tournée vers elle-même, qui recoupe davantage les autres Lisp que des langages plus grand public comme Python ou PHP. Le cliché selon lequel Clojure est le langage le plus puissant a donc une part de vérité, mais il peut surprendre ceux qui ne l’utilisent pas
Nous, développeurs Clojure, y sommes déjà habitués, et parler en présupposant cette supériorité est presque devenu une formule de salutation
Je préfère aussi Clojure pour manipuler les sorties de LLM. Bien sûr, j’utilise toujours Python là où Python est parfaitement adapté