Introduction
Dans le monde actuel du développement de logiciels, les termes « indigène » et « réactif» ont gagné en popularité, devenant des considérations cruciales pour les développeurs, les architectes et les entreprises.
Que vous développiez des applications front-end ou des systèmes back-end, l’approche native et réactive est devenue un élément crucial des exigences non fonctionnelles du développement logiciel moderne. Ce blog vise à explorer la signification de ces deux concepts et pourquoi ils sont devenus si essentiels.
Nous examinerons également de plus près où ces deux concepts s’intégreront dans les trois principales catégories de solutions logicielles courantes dans l’industrie informatique aujourd’hui : Demande-réponse (synchrone), basée sur la file d’attente (asynchrone) et basée sur les événements (Streams/Event Sourcing). Enfin, nous examinerons comment les architectures natives et réactives peuvent apporter des avantages significatifs à chacune de ces catégories.
À propos de « natif »
La conteneurisation est devenue une approche populaire pour déployer des applications dans des environnements cloud modernes. Avec les conteneurs, les applications sont regroupées dans une seule image de conteneur, qui peut ensuite être déployée de manière cohérente dans différents environnements. Cependant, lorsqu’il s’agit d’exécuter des applications dans des conteneurs, il existe deux options principales : s’exécuter en tant que machine virtuelle (VM) traditionnelle ou s’exécuter en tant qu’application native. Les applications natives sont conçues spécifiquement pour la plate-forme cible, ce qui se traduit par de meilleures performances, des temps de démarrage plus rapides, une consommation de mémoire réduite et de meilleures performances d’exécution. Ils peuvent être facilement mis à l’échelle horizontalement, ce qui augmente l’efficacité de l’utilisation des ressources. De plus, l’exécution d’applications en mode natif réduit la surface d’attaque, ce qui rend l’application plus sécurisée. En résumé, les applications natives sont un facteur essentiel de la conteneurisation, offrant de meilleures performances, évolutivité, efficacité des ressources et sécurité, et sont cruciales pour le succès des environnements cloud modernes. Vous pouvez en savoir plus sur Cloud-Native ici.
À propos de « Réactif »
La programmation réactive a gagné en popularité ces dernières années, et pour cause. Un avantage important de la programmation réactive est sa capacité à gérer des applications basées sur des flux ou des files d’attente. Dans de telles applications, le traitement des messages ou des événements entrants est sensible au temps et nécessite une action immédiate. La programmation réactive fournit une solution à ces scénarios en permettant au développeur d’écrire des applications qui peuvent réagir immédiatement aux événements entrants plutôt que d’attendre une réponse de l’événement précédent. Cela signifie que l’application peut gérer de gros volumes de données entrantes sans blocage, ce qui se traduit par une application plus rapide et plus efficace. De plus, la programmation réactive permet une meilleure évolutivité et résilience, car elle peut gérer de grandes quantités de données entrantes sans surcharger le système. En résumé, la programmation réactive est un excellent choix pour développer des applications basées sur des flux ou des files d’attente, car elle permet une réponse immédiate et une gestion efficace de gros volumes de données, ce qui se traduit par une application plus évolutive, résiliente et performante.
Pile technologique
Quarkus est une alternative émergente au framework Spring de RedHat. Il gagne rapidement en popularité en raison de ses performances élevées et de son utilisation efficace des ressources. L’une des principales raisons de sa popularité est sa capacité à utiliser une approche au moment de la compilation pour créer des applications natives, ce qui se traduit par des applications légères et rapides. Cette approche, associée à la prise en charge de GraalVM par Quarkus, permet aux applications Quarkus de consommer un minimum de ressources, ce qui les rend idéales pour s’exécuter dans des environnements à ressources limitées tels que des conteneurs ou des environnements sans serveur.
Quarkus offre également une expérience de développement simplifiée pour les développeurs, avec des outils de développement étendus et une prise en charge du rechargement à chaud. Quarkus est conçu pour fonctionner correctement avec les architectures cloud natives et fournit une prise en charge prête à l’emploi pour plusieurs technologies cloud natives telles que Kubernetes, Istio et Knative.
Quarkus Reactive est un cadre puissant pour la création d’applications réactives, avec des fonctionnalités telles que Panache qui facilitent le travail avec des bases de données telles que MySQL à l’aide d’objets Java classiques (POJO). Avec Panache, les développeurs peuvent créer des entités qui correspondent aux tables de base de données et effectuer des opérations CRUD à l’aide de méthodes simples et sécurisées.
En résumé, Quarkus est une excellente alternative au framework Spring, offrant plusieurs avantages tels que des performances élevées, une utilisation efficace des ressources, un support cloud natif et une expérience de développement simplifiée, ce qui en fait un choix idéal pour les architectures cloud natives modernes.
Kotlin: est un langage de programmation à typage statique qui a été conçu pour être plus concis et expressif que Java tout en étant totalement interopérable avec le code Java. Développé par JetBrains, Kotlin est open source et a rapidement gagné en popularité en raison de sa facilité d’utilisation, de sa syntaxe concise et de l’amélioration de la productivité des développeurs. Kotlin est utilisé pour développer une large gamme d’applications, des applications mobiles Android aux applications côté serveur et au-delà. Son adoption a été encouragée par de grandes entreprises comme Google, Netflix et Pinterest, faisant de Kotlin un choix populaire parmi les développeurs pour le développement de logiciels modernes.
GraphQL : Développé par Facebook, GraphQL est un langage de requête pour les API qui a depuis été mis à la disposition de la communauté des développeurs au sens large. Il offre une option plus efficace, puissante et flexible par rapport à REST pour les API Web modernes. Avec GraphQL, vous pouvez spécifier les données exactes dont vous avez besoin, réduisant ainsi les problèmes de sur-extraction et de sous-extraction. Les fonctionnalités clés sont Mutations et GraphQL-UI qui accompagnent votre API.
Scène de démonstration
Supposons qu’AWS Cloud n’offre pas son pilier crucial de « Fiabilité » et que vous êtes responsable de la gestion de votre application (instances/pods EC2) de manière indépendante. Votre tâche consiste à créer une API réactive, ce qui signifie que vous devez recevoir des notifications en temps réel lorsqu’un pod est résilié ou créé. Laissez-nous développer l’API pour répondre à ces exigences essentielles.
— Même s’il ne s’agit que d’un scénario hypothétique, il peut être alarmant de considérer les défis et les risques potentiels qui peuvent survenir dans une telle situation
Schéma de base de données
Définissez les principaux composants du réseau AWS tels que VPC, région, sous-réseau, EC2, etc.
CREATE TABLE region (
region_id INT NOT NULL AUTO_INCREMENT,
region_name VARCHAR(255) NOT NULL,
PRIMARY KEY (region_id)
);
CREATE TABLE vpc (
vpc_id INT NOT NULL AUTO_INCREMENT,
vpc_name VARCHAR(255) NOT NULL,
region_id INT NOT NULL,
PRIMARY KEY (vpc_id),
FOREIGN KEY (region_id) REFERENCES region(region_id)
);
CREATE TABLE azone(
az_id INT NOT NULL AUTO_INCREMENT,
az_name VARCHAR(255) NOT NULL,
region_id INT NOT NULL,
PRIMARY KEY (az_id),
FOREIGN KEY (region_id) REFERENCES region(region_id)
);
CREATE TABLE subnet (
subnet_id INT NOT NULL AUTO_INCREMENT,
subnet_name VARCHAR(255) NOT NULL,
vpc_id INT NOT NULL,
az_id INT NOT NULL,
PRIMARY KEY (subnet_id),
FOREIGN KEY (vpc_id) REFERENCES vpc(vpc_id),
FOREIGN KEY (az_id) REFERENCES azone(az_id)
);
CREATE TABLE ec2 (
ec2_id INT NOT NULL AUTO_INCREMENT,
ec2_name VARCHAR(255) NOT NULL,
subnet_id INT NOT NULL,
PRIMARY KEY (ec2_id),
FOREIGN KEY (subnet_id) REFERENCES subnet(subnet_id)
);
Maintenant, créons un projet Quarkus en utilisant l’initialisateur de projet d’IntelliJ Idea, ou vous pouvez simplement visiter le site officiel et le créer.
Initialiseur de projet
Modules

Définir vos classes d’entités
@Entity
@Cacheable
@Table(schema = "sysopsdb", name="azone")
class Azone {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name ="az_id")
var id: Long? = null
@Column(name ="az_name")
lateinit var name: String
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "region_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
var region: Region? = null
@OneToMany(cascade = [CascadeType.ALL], fetch = FetchType.EAGER, mappedBy = "azone")
var subnets: Set<Subnet> = HashSet<Subnet>()
}
@Entity
@Cacheable
@Table(schema = "sysopsdb", name="ec2")
class EC2{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name ="ec2_id")
var id: Long? = null
@Column(name ="ec2_name")
lateinit var name: String
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "subnet_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
var subnet: Subnet? = null
}
@Entity
@Cacheable
@Table(schema = "sysopsdb", name="region")
class Region {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name ="region_id")
var id: Long? = null
@Column(name ="region_name")
lateinit var name: String
@OneToMany(cascade = [CascadeType.ALL], fetch = FetchType.EAGER, mappedBy = "region")
val azs: Set<Azone> = HashSet<Azone>()
}
@Entity
@Cacheable
@Table(schema = "sysopsdb", name="subnet")
class Subnet {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name ="subnet_id")
var id: Long? = null
@Column(name ="subnet_name")
lateinit var name: String
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "vpc_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
val vpc: VPC? = null
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "az_id",...