Не се повторувај или не се суши е важен принцип во развојот на софтвер. Овој пост ќе ви покаже како да го примените на конфигурацијата на Apache APISIX.
„Не се повторувај“ (DRY) е принцип на развој на софтвер кој има за цел да го намали повторувањето на информациите кои веројатно ќе се променат, заменувајќи ги со апстракции кои со помала веројатност ќе се променат или користење на нормализација на податоците што на прво место го избегнува вишокот .
Главната идеја зад DRY е дека ако се повторувате и информациите се сменат, тогаш мора да ги ажурирате променетите информации на повеќе места. Тоа не е само дополнителен напор; постои можност да заборавите на тоа и да имате различни информации на различни места. DRY сјае при поправање грешки.
Замислете фрагмент од код кој содржи бубачка. Замислете сега дека сте го дуплирале фрагментот на две различни места. Сега, мора да ја поправите грешката на овие две места, и тоа е полесниот дел; тешко е да се знае за дуплирањето на прво место.
Има големи шанси личноста што се дуплира и таа што поправа се различни. Ако фрагментот бил рефакториран за да може да се сподели и наместо тоа повикан од двете места, треба само да ја поправите грешката на ова едно место.
Повеќето луѓе го поврзуваат DRY со код. Сепак, тоа би можело да биде поограничувачко и спротивно на првичната идеја.
Принципот е формулиран од Енди Хант и Дејв Томас во нивната книга Прагматичен програмер. Тие го применуваат доста широко за да вклучат шеми за бази на податоци, планови за тестирање, систем за градење, дури и документација.
Системите за конфигурација на звук овозможуваат СУШЕЊЕ или дури и го поттикнуваат.
Apache APISIX нуди DRY конфигурација на две места.
Во контекст на е-трговија, вашето почетничко патување за да дефинирате рута на Apache APISIX веројатно започнува вака:
routes: - id: 1 name: Catalog uri: /products* upstream: nodes: "catalog:8080": 1
Ако сте запознаени со APISIX, дефиниравме маршрута до каталогот под /products
URI. Сепак, постои проблем: веројатно сакате потенцијалните клиенти да го прелистуваат каталогот, но сакате да ги спречите луѓето да создаваат, бришат или ажурираат производи. Сепак, рутата стандардно се совпаѓа со секој HTTP метод.
Треба да дозволиме само автентицирани корисници да управуваат со каталогот за да може секој слободно да го прелистува. За да го имплементираме овој пристап, треба да ја поделиме рутата на два дела:
routes: - id: 1 name: Read the catalogue methods: [ "GET", "HEAD" ] #1 uri: /products* upstream: #2 nodes: "catalog:8080": 1 - id: 1 name: Read the catalogue methods: [ "PUT", "POST", "PATCH", "DELETE" ] #3 uri: /products* plugins: key-auth: ~ #4 upstream: #2 nodes: "catalog:8080": 1
key-auth
е наједноставниот приклучок за ова
Безбедносниот проблем го решивме на наједноставен можен начин: со copy-paste. Со тоа, го дуплиравме делот upstream
. Ако треба да ја смениме топологијата, на пр. , со додавање или отстранување јазли, тоа мора да го направиме на две места. Го поразува принципот на СУВО.
Во сценаријата од реалниот свет, особено кога тие вклучуваат контејнери, нема да го имплементирате upstream
со наведување nodes
. Наместо тоа, треба да имплементирате динамично откривање на услугата за да се приспособат на промените во топологијата. Сепак, поентата сè уште стои кога треба да ја промените конфигурацијата или имплементацијата за откривање услуга. Оттука, мојата поента се однесува подеднакво на јазлите и откривањето на услугите.
Заедно со апстракцијата Route , APISIX нуди апстракција Upstream за спроведување на DRY. Горенаведениот фрагмент можеме да го преработиме вака:
upstreams: - id: 1 #1 name: Catalog nodes: "catalog:8080": 1 routes: - id: 1 name: Read the catalogue methods: [ "GET", "HEAD" ] uri: /products* upstream_id: 1 #2 - id: 1 name: Read the catalogue methods: [ "PUT", "POST", "PATCH", "DELETE" ] uri: /products* upstream_id: 1 #2 plugins: key-auth: ~
1
Ако нешто се случи во топологијата, мора да ја ажурираме промената само во единечниот Upstream .
Забележете дека дефинирањето на вграденото upstream
и неговото упатување со upstream_id
меѓусебно се исклучуваат .
Друга област каде што APISIX може да ви помогне да ја исушите вашата конфигурација со апстракцијата на приклучокот . APISIX ги имплементира повеќето функции, ако не и сите, преку приклучоци
Ајде да имплементираме верзии базирани на патеки на нашето API. Треба да го преработиме URL-то пред да го проследиме.
routes: - id: 1 name: Read the catalogue methods: [ "GET", "HEAD" ] uri: /v1/products* upstream_id: 1 plugins: proxy-rewrite: regex_uri: [ "/v1(.*)", "$1" ] #1 - id: 1 name: Read the catalogue methods: [ "PUT", "POST", "PATCH", "DELETE" ] uri: /v1/products* upstream_id: 1 plugins: proxy-rewrite: regex_uri: [ "/v1(.*)", "$1" ] #1
/v1
пред препраќање
Како и со upstream
, делот plugins
е дупликат. Ние, исто така, можеме да ја факторизираме конфигурацијата на приклучокот во посветен објект за конфигурација на приклучокот . Следниот фрагмент го има истиот ефект како оној погоре:
plugin_configs: - id: 1 #1 plugins: proxy-rewrite: regex_uri: [ "/v1(.*)", "$1" ] routes: - id: 1 name: Read the catalogue methods: [ "GET", "HEAD" ] uri: /v1/products* upstream_id: 1 plugin_config_id: 1 #2 - id: 1 name: Read the catalogue methods: [ "PUT", "POST", "PATCH", "DELETE" ] uri: /v1/products* upstream_id: 1 plugin_config_id: 1 #2
Разумните читатели можеби забележале дека ми недостасува дел од конфигурацијата: auth-key
мистериозно исчезна! Навистина, го отстранив заради јасност.
За разлика од upstream
и upstream_id
, plugins
и plugin_config_id
не се исклучуваат меѓусебно . Можеме да го решиме проблемот со само додавање на plugin
што недостасува:
routes: - id: 1 name: Read the catalogue methods: [ "GET", "HEAD" ] uri: /v1/products* upstream_id: 1 plugin_config_id: 1 - id: 1 name: Read the catalogue methods: [ "PUT", "POST", "PATCH", "DELETE" ] uri: /v1/products* upstream_id: 1 plugin_config_id: 1 plugins: key-auth: ~ #1
На овој начин, можете да ја преместите споделената конфигурација во објект plugin_config
и да задржите одредена на местото каде што се применува. Но, што ако истиот приклучок со различни конфигурации се користи во plugin_config
и директно во route
? Документацијата е прилично јасна за тоа:
Consumer
>Consumer Group
>Route
>Plugin Config
>Service
Накратко, конфигурацијата plugin
во route
ја отфрла конфигурацијата во plugin_config_id
. Исто така, ни овозможува да ја обезбедиме променливата apikey
за приклучокот key-auth
кај consumer
и да ја поставиме само во рута. APISIX ќе го најде и користи клучот за секој consumer
!
DRY не е само за код; се работи за управување со податоци воопшто. Конфигурацијата е податок и затоа спаѓа под овој општ чадор.
APISIX нуди две DRY опции: една за upstream
- upstream_id
, и една за plugin
- plugin_config_id
. Возводните текови се ексклузивни; приклучоците дозволуваат отфрлање.
Двата механизми треба да ви помогнат да ја исушите вашата конфигурација и да ја направат поодржлива на долг рок.
За да продолжите понатаму:
Првично објавено во A Java Geek на 1 септември 2024 година