āϏāĻŦāĻžāĻāĻā§ āĻšā§āϝāĻžāϞā§, āĻāĻāĻžāύ⧠āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āϏāĻŋāϰāĻŋāĻā§āϰ āϤā§āϤā§āϝāĻŧ āĻĒā§āϏā§āĻ!

āĻāĻžāĻāĻž āĻŽāĻžāĻāĻā§āϰā§āϏāĻžāϰā§āĻāĻŋāϏ āĻŦāĻŋāĻāĻžāĻļ āĻāϰāĻžāϰ āϏāĻŽāϝāĻŧ, āĻāĻāĻŋ āĻĒā§āϰāĻžāϝāĻŧāĻļāĻ āĻŦāĻŋāĻļā§āĻŦāĻžāϏ āĻāϰāĻž āĻšāϝāĻŧ и āĻĒā§āĻĨāĻ āĻāĻŦāĻ āϏā§āĻŦāĻžāϧā§āύ APIāĨ¤ āĻĄāĻŋāĻĢāϞā§āĻāϰā§āĻĒā§, āĻĒā§āϰā§āĻā§āϰāĻžāĻŽāĻžāϰāϰāĻž āĻāĻŽāύ API āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āϝā§āĻā§āϞāĻŋ āϤāĻžāϰāĻž āĻāϤāĻŋāĻŽāϧā§āϝā§āĻ āĻ
āĻā§āϝāϏā§āϤ, āϝā§āĻšā§āϤ⧠āύāϤā§āύ āĻĢā§āϰā§āĻŽāĻāϝāĻŧāĻžāϰā§āĻ āĻāĻŦāĻ āϰāĻžāύāĻāĻžāĻāĻŽ āĻāĻĒāĻžāĻĻāĻžāύāĻā§āϞāĻŋ āĻļāĻŋāĻāϤ⧠āĻ
āύā§āĻ āϏāĻŽāϝāĻŧ āϞāĻžāĻā§āĨ¤ āĻāĻ āĻāĻŽāϰāĻž āĻāĻŋāĻā§ āĻāύāĻĒā§āϰāĻŋāϝāĻŧ āĻāύā§āύāϝāĻŧāύ āϏāĻšāĻ āĻāϰāĻžāϰ āĻā§āώā§āĻāĻž āĻāϰāĻŦ āĻāĻŦāĻ āĻāĻĒāύāĻžāĻā§ āĻĻā§āĻāĻžāϝāĻŧ āĻāĻŋāĻāĻžāĻŦā§ āĻāĻāĻ āϏāĻžāĻĨā§ āϏā§āĻĒā§āϰāĻŋāĻ API āĻāĻŦāĻ āύāϤā§āύ āĻĻāϰāĻāĻžāϰ⧠āĻŦā§āĻļāĻŋāώā§āĻā§āϝāĻā§āϞāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻšāϝāĻŧ⧎ .
āĻāĻāĻā§ āĻŦāĻŋāϏā§āϤāĻžāϰāĻŋāϤāĻāĻžāĻŦā§, āĻāĻŽāϰāĻž āĻĒā§āϰāĻĨāĻŽā§ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻā§āϞāĻĒāĻžāϰāĻĻā§āϰ āϤāĻžāĻĻā§āϰ āĻĻā§āύāύā§āĻĻāĻŋāύ āĻāĻžāĻā§ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻāĻĒāĻŋāĻāĻ āĻā§āĻāĻžāĻŦā§ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻšāϝāĻŧ āϤāĻž āĻĻā§āĻāĻžāύā§āϰ āĻāύā§āϝ āϏā§āĻĒā§āϰāĻŋāĻ āĻāĻĒāĻŋāĻāĻ āϏāĻŽāϰā§āĻĨāύ āĻāϰ⧠āĻāĻŋāĻāĻžāĻŦā§ āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āϏā§āĻĒā§āϰāĻŋāĻ āĻāĻĒāĻŋāĻāĻ āϏāĻŽāϰā§āĻĨāύ āĻāϰ⧠āϤāĻžāϰ āĻĒāϰāĻŋāϧāĻŋ āĻāĻŦāĻ āĻŦāĻŋāĻļāĻĻ āĻĻā§āĻāĻŦāĨ¤ āϤāĻžāϰāĻĒāϰ⧠āĻāĻŽāϰāĻž āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ APIāĻā§āϞāĻŋ āĻāĻāĻžāϰ āĻāϰāĻŦ, āϝāĻž āĻŽāĻžāĻāĻā§āϰā§āϏāĻžāϰā§āĻāĻŋāϏ āϤā§āϰāĻŋ āĻāϰāĻžāϰ āϏāĻŽāϝāĻŧ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻā§āϞāĻĒāĻžāϰāĻĻā§āϰ āĻāύā§āϝ āĻāĻĒāϝā§āĻā§āĨ¤
āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āĻā§āύ? āĻĒā§āϰāĻĨāĻŽāϤ, āĻāĻāĻŋ āĻšāϞ āϞāĻžāĻāĻ āĻā§āĻĄāĻŋāĻ, āĻ āϰā§āĻĨāĻžā§ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻāĻĒāĻŋāĻāĻ, āϏā§āĻĒā§āϰāĻŋāĻ āĻāĻĒāĻŋāĻāĻ āĻāĻŦāĻ āĻ āύā§āϝāĻžāύā§āϝ āĻāĻžāĻāĻž āĻāĻĒāĻŋāĻāĻ-āĻāϰ āϝā§āĻā§āύ⧠āĻĒāϰāĻŋāĻŦāϰā§āϤāύā§āϰ āϏā§āĻŦāϝāĻŧāĻāĻā§āϰāĻŋāϝāĻŧ āϰāĻŋāϞā§āĻĄāĻŋāĻ, āϝāĻž āĻļā§āϧā§āĻŽāĻžāϤā§āϰ āĻāĻāĻāĻŋ āĻāĻŽāĻžāύā§āĻĄā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻāϰāĻž āĻšāϝāĻŧ: mvn quarkus:devāĨ¤ āĻĻā§āĻŦāĻŋāϤā§āϝāĻŧāϤ, āĻŦāĻŋāĻŦā§āĻāύāĻž āĻāϰāĻž āĻšāϝāĻŧ āĻŦā§āϝāĻā§āϤāĻŋ āĻĒāϰāĻŋāώā§āĻŦāĻž (āϝāĻž āϏā§āĻĒā§āϰāĻŋāĻ, āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ, āĻāĻŦāĻ JPA API āĻĨā§āĻā§ āϏā§āĻĨāĻžāύā§āϝāĻŧ GraalVM āĻāĻŽā§āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāĻāĻāĻŋ āĻŦāĻžāĻāύāĻžāϰāĻŋāϤ⧠āĻāĻŽā§āĻĒāĻžāĻāϞ āĻāϰā§) āĻŽāĻžāϤā§āϰ 0.055 āϏā§āĻā§āύā§āĻĄā§ āĻļā§āϰ⧠āĻšāϝāĻŧ āĻāĻŦāĻ RESTful āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āĻāύā§āĻĄāĻĒāϝāĻŧā§āύā§āĻā§ āĻĒā§āϰāĻžāϝāĻŧ 90 MB RAM (RSS) āύā§āϝāĻŧāĨ¤ āĻ āϧāĻŋāĻāύā§āϤā§, āĻāϰ āϏāĻāĻāϞāύ āύāĻŋāĻā§āĻ āĻļā§āϧā§āĻŽāĻžāϤā§āϰ āĻāĻāĻāĻŋ āĻāĻŽāĻžāύā§āĻĄā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§ āϏāĻā§āĻāĻžāϞāĻŋāϤ āĻšāϝāĻŧ: mvn package -PnativeāĨ¤
āĻāĻŽāϰāĻž āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āϏāĻŽā§āĻĒāϰā§āĻā§ āĻŦāĻŋāϏā§āϤāĻžāϰāĻŋāϤ āĻāϞā§āĻāύāĻž āĻāϰāĻŦ āύāĻž, āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻā§āϞāĻĒāĻžāϰāĻĻā§āϰ āĻŦā§āĻāϤ⧠āϏāĻžāĻšāĻžāϝā§āϝ āĻāϰāĻžāϰ āĻāύā§āϝ āϝ⧠āϤāĻžāϰāĻž āĻā§āĻāĻžāĻŦā§ āϏā§āĻĒā§āϰāĻŋāĻ āĻāĻĒāĻŋāĻāĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻĒāĻžāϰ⧠āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ⧠āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ API āĻāϰ āϏāĻžāĻĨā§āĨ¤
āϧāĻžāϰāĻ āĻāĻŦāĻ āĻā§āĻŦāĻžāϰāύā§āĻāϏ
āĻāĻ āύāĻŋāĻŦāύā§āϧāĻāĻŋāĻā§ āϏāĻšāĻ āϰāĻžāĻāϤā§, āĻāĻŽāϰāĻž āĻāĻāĻžāύ⧠āĻļā§āϧā§āĻŽāĻžāϤā§āϰ āĻāĻā§āĻ-āϏā§āϤāϰā§āϰ āϏāĻšāĻžāϝāĻŧāϤāĻžāϰ āĻĻāĻŋāĻāĻā§āϞāĻŋ āĻāĻāĻžāϰ āĻāϰāĻŦ⧎ āĻāĻžāϰāĻŖ āĻāĻāĻž āĻŦā§āĻāĻž āĻā§āϰā§āϤā§āĻŦāĻĒā§āϰā§āĻŖāĨ¤ Quarkus āĻā§ Kubernetes-āĻāϰ āĻāύā§āϝ āĻāĻāĻāĻŋ āĻāĻžāĻāĻž āϏā§āĻā§āϝāĻžāĻ āĻšāĻŋāϏāĻžāĻŦā§ āĻ āĻŦāϏā§āĻĨāĻžāύ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§, āĻāĻāĻŋ āĻāĻžāĻāĻž āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āĻāĻŦāĻ āĻĒāϰāĻŋāώā§āĻŦāĻžāĻā§āϞāĻŋāϰ āĻŽā§āĻŽāϰāĻŋ āĻāϰāĻ āĻāĻŦāĻ āϏā§āĻāĻžāϰā§āĻāĻāĻĒā§āϰ āϏāĻŽāϝāĻŧ āĻāĻŽāĻžāύā§āϰ āĻāύā§āϝ āĻĄāĻŋāĻāĻžāĻāύ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§, āĻāĻŦāĻ āĻĢāϞāϏā§āĻŦāϰā§āĻĒ, āĻšā§āϏā§āĻā§ āϤāĻžāĻĻā§āϰ āĻāύāϤā§āĻŦ āĻŦāĻžāĻĄāĻŧāĻžāϤ⧠āĻāĻŦāĻ āϏāĻžāĻŽāĻā§āϰāĻŋāĻ āĻāϰāĻ āĻāĻŽāĻžāϤā§āĨ¤
āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏāĻ Kubernetes āϏāĻŽā§āĻĒāĻĻ āĻāĻŦāĻ āĻ āĻĢāĻžāϰ Kubernetes āĻāĻŦāĻ Red Hat OpenShift āĻĒā§āϞā§āϝāĻžāĻāĻĢāϰā§āĻŽā§ āϏā§āĻĨāĻžāĻĒāύāĻžāϰ āĻāύā§āϝāĨ¤ āĻāĻĒāϰāύā§āϤā§, Quarkus āϏā§āĻŦāϝāĻŧāĻāĻā§āϰāĻŋāϝāĻŧāĻāĻžāĻŦā§ Dockerfile.jvm (JVM āĻĒā§āϝāĻžāĻā§āĻāĻŋāĻ) āĻāĻŦāĻ Dockerfile.native (āύā§āĻāĻŋāĻ āĻŦāĻžāĻāύāĻžāϰāĻŋ āĻĒā§āϝāĻžāĻā§āĻāĻŋāĻ) āĻĢāĻžāĻāϞ āϤā§āϰāĻŋ āĻāϰ⧠āϝāĻž āĻāύāĻā§āĻāύāĻžāϰ āϤā§āϰāĻŋāϰ āĻāύā§āϝ āĻĒā§āϰāϝāĻŧā§āĻāύāĨ¤
āĻ āĻŦāĻļā§āώā§, āϞāĻā§āώā§āϝ āϏā§āĻĨāĻžāĻĒāύāĻžāϰ āĻĒāϰāĻŋāĻŦā§āĻļ āĻšāĻŋāϏāĻžāĻŦā§ Kubernetes-āĻ āĻĢā§āĻāĻžāϏ āĻāϰā§, Quarkus āĻāĻžāĻāĻž āĻĢā§āϰā§āĻŽāĻāϝāĻŧāĻžāϰā§āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āύāĻž āϝā§āĻāĻžāύ⧠āĻāĻāĻ āϧāϰāύā§āϰ āĻāĻžāϰā§āϝāĻāĻžāϰāĻŋāϤāĻž āĻā§āĻŦāĻžāϰāύā§āĻāϏ āĻĒā§āϞā§āϝāĻžāĻāĻĢāϰā§āĻŽā§āϰ āϏā§āϤāϰā§āĻ āĻĒā§āϰāϝāĻŧā§āĻ āĻāϰāĻž āĻšāϝāĻŧāĨ¤ āϏāĻžāϰāĻŖāĻŋ 1 āĻā§āĻŦāĻžāϰāύā§āĻāϏ āĻāĻŦāĻ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻā§āϞāĻĒāĻžāϰāĻĻā§āϰ āĻĻā§āĻŦāĻžāϰāĻž āĻŦā§āϝāĻŦāĻšā§āϤ āϏāĻžāϧāĻžāϰāĻŖ āĻāĻžāĻāĻž āĻĢā§āϰā§āĻŽāĻāϝāĻŧāĻžāϰā§āĻāĻā§āϞāĻŋāϰ āĻŽāϧā§āϝ⧠āĻāĻžāϰā§āϝāĻāϰ⧠āĻāĻŋāĻ āĻŋāĻĒāϤā§āϰā§āϰ āĻāĻāĻāĻŋ āĻŽāĻžāύāĻāĻŋāϤā§āϰ āϏāϰāĻŦāϰāĻžāĻš āĻāϰā§āĨ¤
āϏāĻžāϰāĻŖā§ 1. āĻāĻžāĻāĻž āĻĢā§āϰā§āĻŽāĻāϝāĻŧāĻžāϰā§āĻ āĻāĻŦāĻ āĻā§āĻŦāĻžāϰāύā§āĻāϏā§āϰ āĻŽāϧā§āϝ⧠āĻāĻžāϰā§āϝāĻāϰ⧠āĻāĻŋāĻ āĻŋāĻĒāϤā§āϰā§āϰ āĻŽāĻžāύāĻāĻŋāϤā§āϰāĨ¤
āĻā§āϰāĻŋāϝāĻŧāĻžāĻŽā§āϞāĻ
āĻāϤāĻŋāĻšā§āϝāĻŦāĻžāĻšā§ āĻŦāϏāύā§āϤ āĻŦā§āĻ
Kubernetes
āĻĒāϰāĻŋāώā§āĻŦāĻž āĻāĻŦāĻŋāώā§āĻāĻžāϰ
āĻāĻāϰā§āĻāĻž
āĻĄāĻŋāĻāύāĻāϏ
āĻāύāĻĢāĻŋāĻāĻžāϰā§āĻļāύ
āϏā§āĻĒā§āϰāĻŋāĻ āĻā§āϞāĻžāĻāĻĄ āĻāύāĻĢāĻŋāĻāĻžāϰā§āĻļāύ
āĻŽāĻžāύāĻāĻŋāϤā§āϰ/āϏāĻŋāĻā§āϰā§āĻ āĻāύāĻĢāĻŋāĻāĻžāϰ āĻāϰā§āύ
āĻāĻžāϰāϏāĻžāĻŽā§āϝ āϞā§āĻĄ āĻāϰā§āύ
āĻĢāĻŋāϤāĻž (āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ āϏāĻžāĻāĻĄ)
āϏāĻžāϰā§āĻāĻŋāϏ, āϰā§āĻĒā§āϞāĻŋāĻā§āĻļāύ āĻāύā§āĻā§āϰā§āϞāĻžāϰ (āϏāĻžāϰā§āĻāĻžāϰ āϏāĻžāĻāĻĄ)
āĻāĻĻāĻžāĻšāϰāĻŖ āĻĨā§āĻā§ āĻā§āĻĄ āĻāĻŽā§āĻĒāĻžāĻāϞ āĻāĻŦāĻ āϰāĻžāύ āĻāϰāĻž
āĻāĻ āύāĻŋāĻŦāύā§āϧ⧠āĻāĻŽāϰāĻž āĻāϞā§āϞā§āĻ āĻāϰāĻŋ , āϝā§āĻāĻžāύ⧠āϏā§āĻĒā§āϰāĻŋāĻ āĻāĻŦāĻ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ API āĻāĻŦāĻ āĻāĻŽāύāĻāĻŋ āĻāĻāĻ āĻāĻžāĻāĻž āĻā§āϞāĻžāϏ āĻāĻāϏāĻžāĻĨā§ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āĻšāϝāĻŧāĨ¤ āĻāĻ āĻāĻĻāĻžāĻšāϰāĻŖā§āϰ āĻā§āĻĄāĻāĻŋ āĻāĻŽāĻžāύā§āĻĄ āϞāĻžāĻāύ āĻĨā§āĻā§ āĻāĻŽā§āĻĒāĻžāĻāϞ āĻāĻŦāĻ āĻāĻžāϞāĻžāύ⧠āϝā§āϤ⧠āĻĒāĻžāϰā§, āĻŦāĻŋāϏā§āϤāĻžāϰāĻŋāϤ āĻāĻžāύāĻžāϰ āĻāύā§āϝ README.md āĻĢāĻžāĻāϞāĻāĻŋ āĻĻā§āĻā§āύāĨ¤
āϏā§āĻĒā§āϰāĻŋāĻ āĻĢā§āϰā§āĻŽāĻāϝāĻŧāĻžāϰā§āĻ API
āĻāύāĻā§āĻāĻļāύ āύāĻŋāϰā§āĻāϰāϤāĻž
āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āĻāĻāĻāĻŋ āĻĒāϰāĻŋāϏā§āĻŽāĻž āϏāĻŽāϰā§āĻĨāύ āĻāϰ⧠āĻāĻŦāĻ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄāĻŋāĻĒā§āύāĻĄā§āύā§āϏāĻŋ āĻāύāĻā§āĻāĻļāύ (āϏā§āĻĒā§āϰāĻŋāĻ āĻĄāĻŋāĻāĻ) āĻāĻĒāĻŋāĻāĻāĨ¤ āĻāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āύāĻŋāϝāĻŧā§ āĻāĻžāĻ āĻāϰā§āύ, , āϤāĻžāĻšāϞ⧠āĻāĻĒāύāĻŋ āĻāϤāĻŋāĻŽāϧā§āϝā§āĻ CDI āĻāϰ āϏāĻžāĻĨā§ āĻā§āĻŦ āĻĒāϰāĻŋāĻāĻŋāϤāĨ¤ āĻ āύā§āϝāĻĻāĻŋāĻā§, āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻā§āϞāĻĒāĻžāϰāϰāĻž āϏā§āĻĒā§āϰāĻŋāĻ āĻĄāĻŋāĻāĻ-āĻāϰ āϏāĻžāĻĨā§ āϏāĻžāĻŽāĻā§āĻāϏā§āϝ āĻ āϰā§āĻāύ āĻāϰāϤ⧠āϏā§āĻĒā§āϰāĻŋāĻ DI API-āĻāϰ āĻāύā§āϝ āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āĻāĻā§āϏāĻā§āύāĻļāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻĒāĻžāϰā§āĨ¤ āϏāĻŽāϰā§āĻĨāĻŋāϤ āϏā§āĻĒā§āϰāĻŋāĻ DI API āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāϰ āĻāĻĻāĻžāĻšāϰāĻŖāĻā§āϞāĻŋ āϏāĻžāϰāĻŖāĻŋ 2 āĻ āĻĻā§āĻāϝāĻŧāĻž āĻšāϝāĻŧā§āĻā§āĨ¤
Đ āϏāĻŋāĻĄāĻŋāĻāĻ āĻāĻŦāĻ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄāĻŋāĻĒā§āύāĻĄā§āύā§āϏāĻŋ āĻāύāĻā§āĻāĻļāύ āĻāĻāϝāĻŧāĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āĨ¤ āĻāĻ āĻŦāĻŋāώāϝāĻŧā§ āĻāϰāĻ āϤāĻĨā§āϝ āĻāĻŦāĻ āĻāĻĻāĻžāĻšāϰāĻŖā§āϰ āĻāύā§āϝ, āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āĻāĻžāĻāĻĄ āĻĻā§āĻā§āύ .
āϏāĻžāϰāĻŖāĻŋ 2. āϏāĻŽāϰā§āĻĨāĻŋāϤ āϏā§āĻĒā§āϰāĻŋāĻ DI API āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāϰ āĻāĻĻāĻžāĻšāϰāĻŖāĨ¤
āϏāĻŽāϰā§āĻĨāĻŋāϤ āϏā§āĻĒā§āϰāĻŋāĻ DI āĻŦā§āĻļāĻŋāώā§āĻā§āϝ
āĻāĻĻāĻžāĻšāϰāĻŖ
āĻāύāϏā§āĻā§āϰāĻžāĻā§āĻāϰ āĻāύāĻā§āĻāĻļāύ
public PersonSpringController(
PersonSpringRepository personRepository, // injected
PersonSpringMPService personService) { // injected
this.personRepository = personRepository;
this.personService = personService;
}
āĻĢāĻŋāϞā§āĻĄ āĻāύāĻā§āĻāĻļāύ
@Autowired
@RestClient
SalutationRestClient salutationRestClient;
@Value("${fallbackSalutation}")
String fallbackSalutation;
@āĻāύāĻĢāĻŋāĻāĻžāϰā§āĻļāύ
@Configuration
public class AppConfiguration {
@Bean(name = "capitalizeFunction")
public StringFunction capitalizer() {
return String::toUpperCase;
}
}
@Component("noopFunction")
public class NoOpSingleStringFunction implements StringFunction {
@Override
public String apply(String s) {
return s;
}
}
@Service
public class MessageProducer {
@Value("${greeting.message}")
String message;
public String getPrefix() {
return message;
}
}
āĻāϝāĻŧā§āĻŦ āĻĢā§āϰā§āĻŽāĻāϝāĻŧāĻžāϰā§āĻ
āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰāĻž āĻĒāĻāύā§āĻĻ āĻāϰāĻŦā§āύ āϝ⧠āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ āĻāϝāĻŧā§āĻŦ āĻĒā§āϰā§āĻā§āϰāĻžāĻŽāĻŋāĻ āĻŽāĻĄā§āϞ āĻšāĻŋāϏāĻžāĻŦā§ JAX-RS, āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āϰā§āϏā§āĻ āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ, JSON-P, āĻāĻŦāĻ JSON-B āϏāĻŽāϰā§āĻĨāύ āĻāϰā§āĨ¤ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻā§āϞāĻĒāĻžāϰāϰāĻž āϏā§āĻĒā§āϰāĻŋāĻ āĻāϝāĻŧā§āĻŦ API, āĻŦāĻŋāĻļā§āώ āĻāϰ⧠REST āĻāύā§āĻāĻžāϰāĻĢā§āϏā§āϰ āĻāύā§āϝ āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏā§āϰ āϏāĻžāĻŽā§āĻĒā§āϰāϤāĻŋāĻ āϏāĻŽāϰā§āĻĨāύ⧠āϏāύā§āϤā§āώā§āĻ āĻšāĻŦā§āĨ¤ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄāĻŋāĻāĻ-āĻāϰ āĻŽāϤā§, āϏā§āĻĒā§āϰāĻŋāĻ āĻāϝāĻŧā§āĻŦ API āϏāĻŽāϰā§āĻĨāύā§āϰ āĻŽā§āϞ āϞāĻā§āώā§āϝ āĻšāϞ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻā§āϞāĻĒāĻžāϰāĻĻā§āϰ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ API-āĻāϰ āϏāĻžāĻĨā§ āĻāĻāϤā§āϰ⧠āϏā§āĻĒā§āϰāĻŋāĻ āĻāϝāĻŧā§āĻŦ API āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āϏāĻā§āώāĻŽ āĻāϰāĻžāĨ¤ āĻāĻŋāĻāĻžāĻŦā§ āϏāĻŽāϰā§āĻĨāĻŋāϤ āϏā§āĻĒā§āϰāĻŋāĻ āĻāϝāĻŧā§āĻŦ āĻāĻĒāĻŋāĻāĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻšāϝāĻŧ āϤāĻžāϰ āĻāĻĻāĻžāĻšāϰāĻŖ āϏāĻžāϰāĻŖāĻŋ 3-āϤ⧠āĻĻā§āĻāϝāĻŧāĻž āĻšāϝāĻŧā§āĻā§ āĻāĻŦāĻ āĻāĻ āĻŦāĻŋāώāϝāĻŧā§ āĻāϰāĻ āϤāĻĨā§āϝ āĻ āĻāĻĻāĻžāĻšāϰāĻŖ āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āĻāĻŋāĻāĻā§āϰāĻŋāϝāĻŧāĻžāϞ-āĻ āĻĒāĻžāĻāϝāĻŧāĻž āϝāĻžāĻŦā§ .
āϏāĻžāϰāĻŖāĻŋ 3. āϏāĻŽāϰā§āĻĨāĻŋāϤ āϏā§āĻĒā§āϰāĻŋāĻ āĻāϝāĻŧā§āĻŦ API āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāϰ āĻāĻĻāĻžāĻšāϰāĻŖāĨ¤
āϏāĻŽāϰā§āĻĨāĻŋāϤ āϏā§āĻĒā§āϰāĻŋāĻ āĻāϝāĻŧā§āĻŦ āĻŦā§āĻļāĻŋāώā§āĻā§āϝ
āĻāĻĻāĻžāĻšāϰāĻŖ
@āϰā§āϏā§āĻ āĻāύā§āĻā§āϰā§āϞāĻžāϰ
@RequestMapping
@RestController
@RequestMapping("/person")
public class PersonSpringController {
...
...
...
}
@āĻā§āĻāĻŽā§āϝāĻžāĻĒāĻŋāĻ
@āĻĒā§āϏā§āĻāĻŽā§āϝāĻžāĻĒāĻŋāĻ
@āĻĒā§āĻāĻŽā§āϝāĻžāĻĒāĻŋāĻ
@āĻĄāĻŋāϞāĻŋāĻāĻŽā§āϝāĻžāĻĒāĻŋāĻ
@āĻĒā§āϝāĻžāĻāĻŽā§āϝāĻžāĻĒāĻŋāĻ
@RequestParam
@RequestHeader
@MatrixVariable
@āĻĒāĻžāĻĨāĻā§āϰāĻŋāϝāĻŧā§āĻŦāϞ
@āĻā§āĻāĻŋāĻā§āϝāĻžāϞā§
@RequestBody
@ āϰā§āϏāĻĒāύā§āϏ āϏā§āĻā§āϝāĻžāĻāĻžāϏ
@ āĻŦā§āϝāϤāĻŋāĻā§āϰāĻŽ āĻšā§āϝāĻžāύā§āĻĄāϞāĻžāϰ
@RestControllerAdvice (āĻāĻāĻļāĻŋāĻ)
@GetMapping(path = "/greet/{id}",
produces = "text/plain")
public String greetPerson(
@PathVariable(name = "id") long id) {
...
...
...
}
āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻāĻž JPA
āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰāĻžāĻ āĻĒā§āϰāĻļāĻāϏāĻž āĻāϰāĻŦā§āύ āϝ⧠āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āĻšāĻžāĻāĻŦāĻžāϰāύā§āĻ ORM āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠JPA āϏāĻŽāϰā§āĻĨāύ āĻāϰā§āĨ¤ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻā§āϞāĻĒāĻžāϰāĻĻā§āϰ āĻāύā§āϝāĻ āϏā§āϏāĻāĻŦāĻžāĻĻ āϰāϝāĻŧā§āĻā§: āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āϏāĻžāϧāĻžāϰāĻŖ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻāĻž JPA āĻā§āĻāĻž āĻāĻŦāĻ āĻĒā§āϰāĻāĻžāϰāĻā§āϞāĻŋāĻā§ āϏāĻŽāϰā§āĻĨāύ āĻāϰā§ā§ˇ āϏāĻŽāϰā§āĻĨāĻŋāϤ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻāĻž JPA API āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāϰ āĻāĻĻāĻžāĻšāϰāĻŖ āϏāĻžāϰāĻŖāĻŋ 4 āĻ āĻĻā§āĻāϝāĻŧāĻž āĻšāϝāĻŧā§āĻā§āĨ¤
Đ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻāĻž JPA API āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āĻšāϝāĻŧ āĻāĻŦāĻ Quarkus āĻāĻŋāĻāĻā§āϰāĻŋāϝāĻŧāĻžāϞ āύāĻžāĻŽāĻ āĻāϰāĻ āϤāĻĨā§āϝ āĻĒāĻžāĻāϝāĻŧāĻž āϝāĻžāϝāĻŧ .
āϏāĻžāϰāĻŖāĻŋ 4. āϏāĻŽāϰā§āĻĨāĻŋāϤ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻāĻž JPA API āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāϰ āĻāĻĻāĻžāĻšāϰāĻŖāĨ¤
āϏāĻŽāϰā§āĻĨāĻŋāϤ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻāĻž JPA āĻŦā§āĻļāĻŋāώā§āĻā§āϝ
āĻāĻĻāĻžāĻšāϰāĻŖ
CrudRepository
public interface PersonRepository
extends JpaRepository,
PersonFragment {
...
}
āϏāĻāĻā§āϰāĻšāϏā§āĻĨāϞā§āϰ āĻĒā§āϰāϝāĻŧā§āĻ
JpaRepository
āĻĒā§āĻāĻŋāĻāĻāύā§āĻĄ āϏāϰā§āĻāĻŋāĻ āϰāĻŋāĻĒā§āĻāĻŋāĻāϰāĻŋ
public class PersonRepository extends
Repository {
Person save(Person entity);
Optional findById(Person entity);
}
āϏāĻāĻā§āϰāĻšāϏā§āĻĨāϞ āĻāĻŖā§āĻĄ
public interface PersonRepository
extends JpaRepository,
PersonFragment {
...
}
āĻĒā§āϰāĻžāĻĒā§āϤ āĻā§āϝā§āϝāĻŧāĻžāϰ⧠āĻĒāĻĻā§āϧāϤāĻŋ
public interface PersonRepository extends CrudRepository {
List findByName(String name);
Person findByNameBySsn(String ssn);
Optional
findByNameBySsnIgnoreCase(String ssn);
Boolean existsBookByYearOfBirthBetween(
Integer start, Integer end);
}
āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§-āϏāĻāĻā§āĻāĻžāϝāĻŧāĻŋāϤ āĻĒā§āϰāĻļā§āύ
public interface MovieRepository
extends CrudRepository {
Movie findFirstByOrderByDurationDesc();
@Query("select m from Movie m where m.rating = ?1")
Iterator findByRating(String rating);
@Query("from Movie where title = ?1")
Movie findByTitle(String title);
}
āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ API
āĻĻā§āώ āϏāĻšāύāĻļā§āϞāϤāĻž
āĻā§āϝāĻžāϏāĻā§āĻĄāĻŋāĻ āĻŦā§āϝāϰā§āĻĨāϤāĻž āϰā§āϧ āĻāϰāϤ⧠āĻāĻŦāĻ āύāĻŋāϰā§āĻāϰāϝā§āĻā§āϝ āĻŽāĻžāĻāĻā§āϰā§āϏāĻžāϰā§āĻāĻŋāϏ āĻāϰā§āĻāĻŋāĻā§āĻāĻāĻžāϰ āϤā§āϰāĻŋāϰ āĻāύā§āϝ āĻĢāϞā§āĻ āĻāϞāĻžāϰā§āύā§āϏ āĻāύāϏā§āĻā§āϰāĻžāĻā§āĻ āĻā§āĻŦāĻ āĻā§āϰā§āϤā§āĻŦāĻĒā§āϰā§āĻŖāĨ¤ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻā§āϞāĻĒāĻžāϰāϰāĻž āĻŦāĻšā§ āĻŦāĻāϰ āϧāϰ⧠āϤā§āϰā§āĻāĻŋ āϏāĻšāύāĻļā§āϞāϤāĻžāϰ āĻāύā§āϝ āϏāĻžāϰā§āĻāĻŋāĻ-āĻŦā§āϰā§āĻāĻžāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻā§āύāĨ¤ . āϝāĻžāĻāĻšā§āĻ, āĻšāĻžāĻāϏā§āĻā§āϰāĻŋāĻā§āϏ āĻĻā§āϰā§āĻāĻĻāĻŋāύ āϧāϰ⧠āĻāĻĒāĻĄā§āĻ āĻāϰāĻž āĻšāϝāĻŧāύāĻŋ, āϤāĻŦā§ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞā§āϰ āĻĢāϞā§āĻ āĻāϞāĻžāϰā§āύā§āϏ āĻāĻāύ āϏāĻā§āϰāĻŋāϝāĻŧāĻāĻžāĻŦā§ āĻŦāĻŋāĻāĻžāĻļ āĻāϰāĻā§ āĻāĻŦāĻ āĻāϰ āĻĒāĻŋāĻāύ⧠āĻŦā§āĻļ āĻāϝāĻŧā§āĻ āĻŦāĻāϰā§āϰ āĻā§āĻĒāĻžāĻĻāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āϰāϝāĻŧā§āĻā§āĨ¤ āĻ āϤāĻāĻŦ, āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ⧠āĻĒāϰāĻŋāώā§āĻŦāĻžāĻā§āϞāĻŋāϰ āύāĻŋāϰā§āĻāϰāϝā§āĻā§āϝāϤāĻž āĻāύā§āύāϤ āĻāϰāĻžāϰ āĻāύā§āϝ, āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻĢāϞā§āĻ āĻāϞāĻžāϰā§āύā§āϏ API āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāϰ āĻĒāϰāĻžāĻŽāϰā§āĻļ āĻĻā§āĻāϝāĻŧāĻž āĻšāĻā§āĻā§, āϝāĻžāϰ āĻāĻĻāĻžāĻšāϰāĻŖ āϏāĻžāϰāĻŖā§ 5 āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§āĨ¤ āĻāĻ āĻŦāĻŋāώāϝāĻŧā§ āĻāϰāĻ āϤāĻĨā§āϝā§āϰ āĻāύā§āϝ, āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āĻŽā§āϝāĻžāύā§āϝāĻŧāĻžāϞ āĻĻā§āĻā§āύ .
āϏāĻžāϰāĻŖāĻŋ 5. āϏāĻŽāϰā§āĻĨāĻŋāϤ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻĢāϞā§āĻ āĻāϞāĻžāϰā§āύā§āϏ API āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāϰ āĻāĻĻāĻžāĻšāϰāĻŖāĨ¤
āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻĢāϞā§āĻ āĻāϞāĻžāϰā§āύā§āϏ āĻŦā§āĻļāĻŋāώā§āĻā§āϝ
āĻŦāĻŋāĻŦāϰāĻŖ
āĻāĻĻāĻžāĻšāϰāĻŖ
@āĻ ā§āϝāĻžāϏāĻŋāύāĻā§āϰā§āύāĻžāϏ
āĻāĻāĻāĻŋ āĻĒā§āĻĨāĻ āĻĨā§āϰā§āĻĄā§ āϝā§āĻā§āϤāĻŋ āύāĻŋāϰā§āĻŦāĻžāĻš āĻāϰāĻž āĻšāĻā§āĻā§
@Asynchronous
@Retry
public Future<String> getSalutation() {
...
return future;
}
@āĻŦāĻžāϞā§āĻāĻšā§āĻĄ
āĻāĻāϝā§āĻā§ āĻ āύā§āϰā§āϧā§āϰ āϏāĻāĻā§āϝāĻž āϏā§āĻŽāĻŋāϤ āĻāϰā§āύ
@Bulkhead(5)
public void fiveConcurrent() {
makeRemoteCall(); //...
}
@āϏāĻžāϰā§āĻāĻŋāĻ āĻŦā§āϰā§āĻāĻžāϰ
āϏā§āĻŽāĻžāϰā§āĻ āĻŦā§āϝāϰā§āĻĨāϤāĻž āĻšā§āϝāĻžāύā§āĻĄāϞāĻŋāĻ āĻāĻŦāĻ āĻŦā§āϝāϰā§āĻĨāϤāĻž āĻĨā§āĻā§ āĻĒā§āύāϰā§āĻĻā§āϧāĻžāϰ
@CircuitBreaker(delay=500 // milliseconds
failureRatio = .75,
requestVolumeThreshold = 20,
successThreshold = 5)
@Fallback(fallbackMethod = "fallback")
public String getSalutation() {
makeRemoteCall(); //...
}
@āĻĒāĻŋāĻā§ āĻšāĻ
āĻŦā§āϝāϰā§āĻĨāϤāĻžāϰ āĻā§āώā§āϤā§āϰ⧠āĻŦāĻŋāĻāϞā§āĻĒ āϝā§āĻā§āϤāĻŋ āĻāϞ āĻāϰāĻž
@Timeout(500) // milliseconds
@Fallback(fallbackMethod = "fallback")
public String getSalutation() {
makeRemoteCall(); //...
}
public String fallback() {
return "hello";
}
āĻ āύā§āϰā§āϧ āĻŦā§āϝāϰā§āĻĨ āĻšāϞ⧠āĻĒā§āύāϰāĻžāϝāĻŧ āĻā§āώā§āĻāĻž āĻāϰā§āύ
@Retry(maxRetries=3)
public String getSalutation() {
makeRemoteCall(); //...
}
āĻŦā§āϝāϰā§āĻĨāϤāĻž āύāĻŋāϝāĻŧāύā§āϤā§āϰāĻŖā§āϰ āϏāĻŽāϝāĻŧāϏā§āĻŽāĻž
@Timeout(value = 500 ) // milliseconds
@Fallback(fallbackMethod = "fallback")
public String getSalutation() {
makeRemoteCall(); //...
}
āĻā§āĻāĻŋāĻ āϏāĻžāϰā§āĻāĻŋāϏ (āĻĒāϰāĻŋāώā§āĻŦāĻž āϏā§āĻŦāĻžāϏā§āĻĨā§āϝ)
Kubernetes āĻĒā§āϞā§āϝāĻžāĻāĻĢāϰā§āĻŽāĻā§āϞāĻŋ āĻŦāĻŋāĻļā§āώ āĻĒāϰāĻŋāώā§āĻŦāĻžāĻā§āϞāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāύā§āĻā§āĻāύāĻžāϰāĻā§āϞāĻŋāϰ āϏā§āĻŦāĻžāϏā§āĻĨā§āϝ āĻĒāϰā§āϝāĻŦā§āĻā§āώāĻŖ āĻāϰā§āĨ¤ āĻ āύā§āϤāϰā§āύāĻŋāĻšāĻŋāϤ āĻĒā§āϞā§āϝāĻžāĻāĻĢāϰā§āĻŽāĻāĻŋāĻā§ āĻĒāϰāĻŋāώā§āĻŦāĻžāĻā§āϞāĻŋ āύāĻŋāϰā§āĻā§āώāĻŖ āĻāϰāĻžāϰ āĻ āύā§āĻŽāϤāĻŋ āĻĻā§āĻāϝāĻŧāĻžāϰ āĻāύā§āϝ, āϏā§āĻĒā§āϰāĻŋāĻ āĻŦāĻŋāĻāĻžāĻļāĻāĻžāϰā§āϰāĻž āϏāĻžāϧāĻžāϰāĻŖāϤ āĻāĻāĻāĻŋ āĻāĻžāϏā§āĻāĻŽ āĻšā§āϞāĻĨ āĻāύā§āĻĄāĻŋāĻā§āĻāϰ āĻāĻŦāĻ āϏā§āĻĒā§āϰāĻŋāĻ āĻŦā§āĻ āĻ ā§āϝāĻžāĻāĻā§āϝāĻŧā§āĻāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āĨ¤ āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏā§, āĻāĻāĻŋ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻšā§āϞāĻĨ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāϰāĻž āϝā§āϤ⧠āĻĒāĻžāϰā§, āϝāĻž āĻĄāĻŋāĻĢāϞā§āĻāĻāĻžāĻŦā§ āĻāĻāĻāĻŋ āĻā§āĻŦāύā§āϤāϤāĻž āĻĒāϰā§āĻā§āώāĻž āĻāϰā§, āĻāĻŋāύā§āϤ⧠āĻāĻāĻ āϏāĻžāĻĨā§ āϏāĻā§āĻŦāϤāĻž āĻāĻŦāĻ āĻĒā§āϰāϏā§āϤā§āϤāĻŋ āĻĒāϰā§āĻā§āώāĻž āĻāϰāĻžāϰ āĻāύā§āϝ āĻāύāĻĢāĻŋāĻāĻžāϰ āĻāϰāĻž āϝā§āϤ⧠āĻĒāĻžāϰā§āĨ¤ āĻā§āĻāĻžāĻŦā§ āϏāĻŽāϰā§āĻĨāĻŋāϤ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻšā§āϞāĻĨ āĻāĻĒāĻŋāĻāĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦā§āύ āϤāĻžāϰ āĻāĻĻāĻžāĻšāϰāĻŖ āϏāĻžāϰāĻŖāĻŋ 6-āĻ āĻĻā§āĻāϝāĻŧāĻž āĻšāϝāĻŧā§āĻā§ āĻāĻŦāĻ āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āĻŽā§āϝāĻžāύā§āϝāĻŧāĻžāϞ⧠āĻ āϤāĻŋāϰāĻŋāĻā§āϤ āϤāĻĨā§āϝ āĻĻā§āĻāϝāĻŧāĻž āĻšāϝāĻŧā§āĻā§ .
āϏāĻžāϰāĻŖāĻŋ 6: āϏāĻŽāϰā§āĻĨāĻŋāϤ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻšā§āϞāĻĨ API-āĻāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰā§āϰ āĻāĻĻāĻžāĻšāϰāĻŖāĨ¤
āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āϏā§āĻŦāĻžāϏā§āĻĨā§āϝ āĻŦā§āĻļāĻŋāώā§āĻā§āϝ
āĻŦāĻŋāĻŦāϰāĻŖ
āĻāĻĻāĻžāĻšāϰāĻŖ
@āϞāĻžāĻāĻāύā§āϏ
āĻĒā§āϞā§āϝāĻžāĻāĻĢāϰā§āĻŽ āϰāĻŋāĻŦā§āĻ āĻŦā§āϝāϰā§āĻĨ āĻāύā§āĻā§āĻāύāĻžāϰāĻžāĻāĻāĻĄ āĻ
ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ
āĻļā§āώāĻĒā§āϰāĻžāύā§āϤ:
āĻšā§āϏā§āĻ: 8080/āϏā§āĻŦāĻžāϏā§āĻĨā§āϝ/āϞāĻžāĻāĻ
@Liveness
public class MyHC implements HealthCheck {
public HealthCheckResponse call() {
...
return HealthCheckResponse
.named("myHCProbe")
.status(ready ? true:false)
.withData("mydata", data)
.build();
}
@āĻĒā§āϰāϏā§āϤā§āϤāĻŋ
āĻĒā§āϞā§āϝāĻžāĻāĻĢāϰā§āĻŽāĻāĻŋ āĻĒā§āϰāϏā§āϤā§āϤ āύāĻž āĻšāϞ⧠āĻāύāĻā§āĻāύāĻžāϰāĻžāĻāĻāĻĄ āĻ
ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύāĻā§āϞāĻŋāϤ⧠āĻā§āϰā§āϝāĻžāĻĢāĻŋāĻ āĻĒāĻžāĻ āĻžāĻŦā§ āύāĻž
āĻļā§āώāĻĒā§āϰāĻžāύā§āϤ:
āĻšā§āϏā§āĻ:8080/āϏā§āĻŦāĻžāϏā§āĻĨā§āϝ/āĻĒā§āϰāϏā§āϤā§āϤ
@Readiness
public class MyHC implements HealthCheck {
public HealthCheckResponse call() {
...
return HealthCheckResponse
.named("myHCProbe")
.status(live ? true:false)
.withData("mydata", data)
.build();
}
āĻŽā§āĻā§āϰāĻŋāĻā§āϏ
āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύāĻā§āϞāĻŋ āĻšāϝāĻŧ āĻ āĻĒāĻžāϰā§āĻļāύāĻžāϞ āĻāĻĻā§āĻĻā§āĻļā§āϝ⧠(āĻĒāĻžāϰāĻĢāϰāĻŽā§āϝāĻžāύā§āϏ āĻāϏāĻāϞāĻāĻā§āϞāĻŋ āύāĻŋāϰā§āĻā§āώāĻŖ āĻāϰāĻžāϰ āĻāύā§āϝ) āĻŦāĻž āĻ -āĻ āĻĒāĻžāϰā§āĻļāύāĻžāϞ āĻāĻĻā§āĻĻā§āĻļā§āϝ⧠(āĻŦā§āϝāĻŦāϏāĻžāϝāĻŧāĻŋāĻ āĻāϏāĻāϞāĻ) āĻāύā§āϝ āĻŽā§āĻā§āϰāĻŋāĻā§āϏ āĻĒā§āϰāĻĻāĻžāύ āĻāϰā§āĨ¤ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻā§āϞāĻĒāĻžāϰāϰāĻž āϏā§āĻĒā§āϰāĻŋāĻ āĻŦā§āĻ āĻ ā§āϝāĻžāĻāĻā§āϝāĻŧā§āĻāϰ āĻāĻŦāĻ āĻŽāĻžāĻāĻā§āϰā§āĻŽāĻŋāĻāĻžāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻŽā§āĻā§āϰāĻŋāĻā§āϏ āĻĒā§āϰāĻĻāĻžāύ āĻāϰā§āĨ¤ āĻĒāϰāĻŋāĻŦāϰā§āϤā§, āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āĻŦā§āϏāϞāĻžāĻāύ āĻŽā§āĻā§āϰāĻŋāĻā§āϏ (āĻā§āĻāĻŋāĻāĻŽ āĻāĻŦāĻ āĻ āĻĒāĻžāϰā§āĻāĻŋāĻ āϏāĻŋāϏā§āĻā§āĻŽ), āĻā§āύā§āĻĄāϰ āĻŽā§āĻā§āϰāĻŋāĻā§āϏ (āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ) āĻāĻŦāĻ āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āĻŽā§āĻā§āϰāĻŋāĻā§āϏ āĻĒā§āϰāĻĻāĻžāύ āĻāϰāϤ⧠āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻŽā§āĻā§āϰāĻŋāĻā§āϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āĨ¤ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻŽā§āĻā§āϰāĻŋāĻā§āϏā§āϰ āĻĒā§āϰāϝāĻŧā§āĻāύ āϝ⧠āĻŦāĻžāϏā§āϤāĻŦāĻžāϝāĻŧāύ JSON āĻāĻŦāĻ OpenMetrics (Prometheus) āĻāĻāĻāĻĒā§āĻ āĻĢāϰā§āĻŽā§āϝāĻžāĻāĻā§āϞāĻŋāĻā§ āϏāĻŽāϰā§āĻĨāύ āĻāϰā§ā§ˇ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻŽā§āĻā§āϰāĻŋāĻā§āϏ āĻāĻĒāĻŋāĻāĻ āĻŦā§āϝāĻŦāĻšāĻžāϰā§āϰ āĻāĻĻāĻžāĻšāϰāĻŖ āϏāĻžāϰāĻŖāĻŋ 7 āĻ āĻĻā§āĻāϝāĻŧāĻž āĻšāϝāĻŧā§āĻā§āĨ¤
Đ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻŽā§āĻā§āϰāĻŋāĻā§āϏ āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āĻŽā§āĻā§āϰāĻŋāĻā§āϏ āĻĒā§āϰāĻĻāĻžāύ āĻāϰāϤ⧠āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āĻšāϝāĻŧ. āĻāϰāĻ āϤāĻĨā§āϝā§āϰ āĻāύā§āϝ, āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āĻŽā§āϝāĻžāύā§āϝāĻŧāĻžāϞ āĻĻā§āĻā§āύ .
āϏāĻžāϰāĻŖā§ 7. āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻŽā§āĻā§āϰāĻŋāĻā§āϏ API āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāϰ āĻāĻĻāĻžāĻšāϰāĻŖāĨ¤
āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻŽā§āĻā§āϰāĻŋāĻā§āϏ āĻŦā§āĻļāĻŋāώā§āĻā§āϝ
āĻŦāĻŋāĻŦāϰāĻŖ
āĻāĻĻāĻžāĻšāϰāĻŖ
@āĻāĻŖāύāĻž āĻāϰāĻž āĻšāϝāĻŧā§āĻā§
āĻāĻāĻāĻŋ āĻāĻžāĻāύā§āĻāĻžāϰ āĻāĻžāĻāύā§āĻāĻžāϰ āύāĻŋāϰā§āĻĻā§āĻļ āĻāϰ⧠āϝāĻž āĻāĻāĻāĻŋ āĻā§āĻāĻžāĻā§āϤ āĻŦāϏā§āϤā§āĻā§ āĻāϤāĻŦāĻžāϰ āĻāϞ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§ āϤāĻž āĻāĻŖāύāĻž āĻāϰā§
@Counted(name = "fallbackCounter",
displayName = "Fallback Counter",
description = "Fallback Counter")
public String salutationFallback() {
return fallbackSalutation;
}
@ConcurrentGauge
āĻāĻāĻāĻŋ āĻā§āĻ āύāĻŋāϰā§āĻĻā§āĻļ āĻāϰ⧠āϝāĻž āĻāĻāĻāĻŋ āĻā§āĻāĻžāϝā§āĻā§āϤ āĻŦāϏā§āϤā§āϤ⧠āϏāĻŽāϏāĻžāĻŽāϝāĻŧāĻŋāĻ āĻāϞā§āϰ āϏāĻāĻā§āϝāĻž āĻāĻŖāύāĻž āĻāϰā§
@ConcurrentGuage(
name = "fallbackConcurrentGauge",
displayName="Fallback Concurrent",
description="Fallback Concurrent")
public String salutationFallback() {
return fallbackSalutation;
}
@ āĻā§āĻ
āĻāĻāĻāĻŋ āĻā§āĻ āϏā§āύā§āϏāϰ āύāĻŋāϰā§āĻĻā§āĻļ āĻāϰ⧠āϝāĻž āĻāĻāĻāĻŋ āĻā§āĻāĻžāϝā§āĻā§āϤ āĻŦāϏā§āϤā§āϰ āĻŽāĻžāύ āĻĒāϰāĻŋāĻŽāĻžāĻĒ āĻāϰā§
@Metered(name = "FallbackGauge",
displayName="Fallback Gauge",
description="Fallback frequency")
public String salutationFallback() {
return fallbackSalutation;
}
@āĻŽāĻŋāĻāĻžāϰā§āĻĄ
āĻāĻāĻāĻŋ āĻŽāĻŋāĻāĻžāϰ āϏā§āύā§āϏāϰ āύāĻŋāϰā§āĻĻā§āĻļ āĻāϰ⧠āϝāĻž āĻāĻāĻāĻŋ āĻā§āĻāĻžāϝā§āĻā§āϤ āĻŦāϏā§āϤā§āϰ āĻāϞ āĻĢā§āϰāĻŋāĻā§āϝāĻŧā§āύā§āϏāĻŋ āύāĻŋāϰā§āĻā§āώāĻŖ āĻāϰā§
@Metered(name = "MeteredFallback",
displayName="Metered Fallback",
description="Fallback frequency")
public String salutationFallback() {
return fallbackSalutation;
}
āĻāĻāĻāĻŋ āĻŽā§āĻā§āϰāĻŋāĻ āĻĒā§āϰāĻŦā§āĻļ āĻŦāĻž āĻāϤā§āĻĒāĻžāĻĻāύ āĻāϰāĻžāϰ āĻāύā§āϝ āĻāĻāĻāĻŋ āĻ āύā§āϰā§āϧ āĻĒā§āϰāĻžāĻĒā§āϤ āĻšāϞ⧠āĻŽā§āĻāĻžāĻĄā§āĻāĻž āϏāĻŽā§āĻĒāϰā§āĻā§ āϤāĻĨā§āϝ āϧāĻžāϰāĻŖāĻāĻžāϰ⧠āĻāĻāĻāĻŋ āĻā§āĻāĻžā§ˇ
@Metric
@Metered(name = "MeteredFallback",
displayName="Metered Fallback",
description="Fallback frequency")
public String salutationFallback() {
return fallbackSalutation;
}
āĻāĻāĻāĻŋ āĻāĻžāĻāĻŽāĻžāϰ āύāĻŋāϰā§āĻĻā§āĻļ āĻāϰ⧠āϝāĻž āĻāĻāĻāĻŋ āĻā§āĻāĻžāϝā§āĻā§āϤ āĻŦāϏā§āϤā§āϰ āϏāĻŽāϝāĻŧāĻāĻžāϞ āĻā§āϰā§āϝāĻžāĻ āĻāϰā§
@Timed(name = "TimedFallback",
displayName="Timed Fallback",
description="Fallback delay")
public String salutationFallback() {
return fallbackSalutation;
}
āĻŽā§āĻā§āϰāĻŋāĻā§āϏ āĻāύā§āĻĄāĻĒāϝāĻŧā§āύā§āĻ
āĻ
ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āĻŽā§āĻā§āϰāĻŋāĻā§āϏ :8080/āĻŽā§āĻā§āϰāĻŋāĻā§āϏ/āĻāĻŦā§āĻĻāύ
āĻŦā§āϏāĻŋāĻ āĻŽā§āĻā§āϰāĻŋāĻā§āϏ :8080/āĻŽā§āĻā§āϰāĻŋāĻā§āϏ/āĻŦā§āϏ
āĻŦāĻŋāĻā§āϰā§āϤāĻž āĻŽā§āĻā§āϰāĻŋāĻā§āϏ :8080/āĻŽā§āĻā§āϰāĻŋāĻā§āϏ/āĻŦāĻŋāĻā§āϰā§āϤāĻž
āϏāĻŽāϏā§āϤ āĻŽā§āĻā§āϰāĻŋāĻā§āϏ :8080/āĻŽā§āĻā§āϰāĻŋāĻā§āϏ
āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āϰā§āϏā§āĻ āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ
āĻŽāĻžāĻāĻā§āϰā§āϏāĻžāϰā§āĻāĻŋāϏāĻā§āϞāĻŋ āĻĒā§āϰāĻžāϝāĻŧāĻ RESTful āĻāύā§āĻĄāĻĒāϝāĻŧā§āύā§āĻ āĻĒā§āϰāĻĻāĻžāύ āĻāϰ⧠āϝā§āĻā§āϞāĻŋāϰ āϏāĻžāĻĨā§ āĻāĻžāĻ āĻāϰāĻžāϰ āĻāύā§āϝ āϏāĻāĻļā§āϞāĻŋāώā§āĻ āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ APIāĻā§āϞāĻŋāϰ āĻĒā§āϰāϝāĻŧā§āĻāύ āĻšāϝāĻŧ⧎ RESTful āĻāύā§āĻĄāĻĒāϝāĻŧā§āύā§āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤā§, āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻā§āϞāĻĒāĻžāϰāϰāĻž āϏāĻžāϧāĻžāϰāĻŖāϤ RestTemplate āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āĨ¤ āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āĻāĻ āϏāĻŽāϏā§āϝāĻž āϏāĻŽāĻžāϧāĻžāύā§āϰ āĻāύā§āϝ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āϰā§āϏā§āĻ āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ āĻāĻĒāĻŋāĻāĻ āĻ āĻĢāĻžāϰ āĻāϰā§, āϝāĻžāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰā§āϰ āĻāĻĻāĻžāĻšāϰāĻŖ āϏāĻžāϰāĻŖāĻŋ 8 āĻ āĻĻā§āĻāϝāĻŧāĻž āĻāĻā§āĨ¤
Đ RESTful āĻāύā§āĻĄāĻĒāϝāĻŧā§āύā§āĻā§āϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āϰā§āϏā§āĻ āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāϰāĻž āĻšāϝāĻŧāĨ¤ āĻāĻ āĻŦāĻŋāώāϝāĻŧā§ āĻāϰāĻ āϤāĻĨā§āϝ āĻāĻŦāĻ āĻāĻĻāĻžāĻšāϰāĻŖ āĻā§āϝāĻŧāĻžāϰā§āĻāĻžāϏ āĻŽā§āϝāĻžāύā§āϝāĻŧāĻžāϞāĻāĻŋāϤ⧠āĻĒāĻžāĻāϝāĻŧāĻž āϝāĻžāĻŦā§ .
āϏāĻžāϰāĻŖā§ 8. āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āϰā§āϏā§āĻ āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ API āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāϰ āĻāĻĻāĻžāĻšāϰāĻŖāĨ¤
āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ āĻŦāĻŋāĻļā§āϰāĻžāĻŽ āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ āĻŦā§āĻļāĻŋāώā§āĻā§āϝ
āĻŦāĻŋāĻŦāϰāĻŖ
āĻāĻĻāĻžāĻšāϰāĻŖ
@āϰā§āĻāĻŋāϏā§āĻāĻžāϰāϰā§āϏā§āĻāĻā§āϞāĻžāϝāĻŧā§āύā§āĻ
REST āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ āĻšāĻŋāϏāĻžāĻŦā§ āĻāĻāĻāĻŋ āĻāĻžāĻāĻĒ āĻāϰāĻž āĻāĻžāĻāĻž āĻāύā§āĻāĻžāϰāĻĢā§āϏ āύāĻŋāĻŦāύā§āϧāύ āĻāϰā§
@RegisterRestClient
@Path("/")
public interface MyRestClient {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getSalutation();
}
@āϰā§āϏā§āĻ āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ
āĻāĻāĻāĻŋ āĻāĻžāĻāĻĒ āĻāϰāĻž REST āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ āĻāύā§āĻāĻžāϰāĻĢā§āϏā§āϰ āĻāĻāĻāĻŋ āĻāĻĻāĻžāĻšāϰāĻŖ āĻŦāĻžāϏā§āϤāĻŦāĻžāϝāĻŧāύ āĻāĻŋāĻšā§āύāĻŋāϤ āĻāϰā§
@Autowired // or @Inject
@RestClient
MyRestClient restClient;
āĻāĻŦāĻžāĻšāύ
āĻāĻāĻāĻŋ REST āĻļā§āώ āĻĒāϝāĻŧā§āύā§āĻ āĻāϞ
System.out.println(
restClient.getSalutation());
mp-rest/url
REST āĻļā§āώ āĻŦāĻŋāύā§āĻĻā§ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻāϰā§
application.properties:
org.example.MyRestClient/mp-rest/url=
http://localhost:8081/myendpoint
āĻĢāϞāĻžāĻĢāϞ
āĻāĻ āĻŦā§āϞāĻā§, āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻāĻāĻžāĻŦā§ āϏā§āĻĒā§āϰāĻŋāĻ āĻĄā§āĻā§āϞāĻĒāĻžāϰāĻĻā§āϰ āϞāĻā§āώā§āϝ āĻāϰā§, āĻāĻŽāϰāĻž āĻāĻžāĻāĻž āĻŽāĻžāĻāĻā§āϰā§āϏāĻžāϰā§āĻāĻŋāϏā§āϏ āĻĄā§āĻā§āϞāĻĒ āĻāϰāϤ⧠Quarkus-āĻāϰ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ API-āĻāϰ āϏāĻžāĻĨā§ āϏā§āĻĒā§āϰāĻŋāĻ API-āĻā§āϞāĻŋ āĻā§āĻāĻžāĻŦā§ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦ āĻāĻŦāĻ āϤāĻžāϰāĻĒāϰ⧠āϏā§āĻā§āϞāĻŋāĻā§ āύā§āĻāĻŋāĻ āĻŦāĻžāĻāύāĻžāϰāĻŋ āĻā§āĻĄā§ āĻāĻŽā§āĻĒāĻžāĻāϞ āĻāϰāĻŦ āϝāĻž āĻļāϤ āĻļāϤ āĻŽā§āĻāĻžāĻŦāĻžāĻāĻ āϰâā§āϝāĻžāĻŽ āϏāĻāϰāĻā§āώāĻŖ āĻāϰ⧠āĻāĻŦāĻ āϞāĻā§āĻ āĻāϰā§āĨ¤ āĻŽāĻŋāϞāĻŋāϏā§āĻā§āύā§āĻĄā§āϰ āĻŦā§āϝāĻžāĻĒāĻžāϰāĨ¤
āĻāĻĒāύāĻŋ āĻāϤāĻŋāĻŽāϧā§āϝā§āĻ āĻŦā§āĻāϤ⧠āĻĒā§āϰā§āĻā§āύ, āϏā§āĻĒā§āϰāĻŋāĻ āĻāĻŦāĻ āĻŽāĻžāĻāĻā§āϰā§āĻĒā§āϰā§āĻĢāĻžāĻāϞ API-āĻāϰ āĻāύā§āϝ āϏāĻŽāϰā§āĻĨāύ āϏāĻŽā§āĻĒāϰā§āĻā§ āĻāϰāĻ āϤāĻĨā§āϝ, āϏā§āĻāϏāĻžāĻĨā§ āĻ
āύā§āϝāĻžāύā§āϝ āĻ
āύā§āĻ āĻĻāϰāĻāĻžāϰ⧠āϤāĻĨā§āϝ āĻĒāĻžāĻāϝāĻŧāĻž āϝāĻžāĻŦā§ .
āĻāϤā§āϏ: www.habr.com
