Saya akan memberi tahu Anda cara membuat layanan relai sederhana untuk frontend (contohnya ada di php), serta betapa mudahnya mendesain API analog di basis dan mendaftarkannya untuk direlay ke frontend.
PS: contoh backend dan frontend akan ada di PHP, database firebird. Tetapi ini tidak perlu, Anda dapat menggunakan bahasa pemrograman apa pun dan database apa pun.
PS: Saya minta jangan angkat topi. Saya tahu sekarang ini tidak populer, karena alasan sosial tertentu, ada lebih banyak spesialis PHP atau Python di pasaran daripada pemrogram SQL, mereka lebih murah, semua orang menyukai ORM. Diyakini bahwa ketika meletakkan logika dalam database, akan lebih sulit untuk mengatur arsitektur layanan mikro. Lebih sulit untuk mengelola kontrol versi. Go mengkompilasi dan harus berjalan lebih cepat daripada database. Sangat populer untuk meletakkan logika bisnis dalam kerangka kerja php, dll.
Ada banyak alasan dan setiap orang memiliki argumen di satu sisi dan di sisi lain, dan masing-masing dapat diperdebatkan secara mendalam.
Tapi artikel ini untuk mereka yang ingin mengatur logika bisnis di database . Tidak ada tujuan di sini untuk mempromosikan metode seperti itu. Mohon dikoreksi di komentar.
Secara umum, metode ini sangat sederhana dan mengganggu dalam hal kecepatan. Jika Anda menulis relai layanan mikro yang kompeten dan secara aktif menggunakan tabel layanan dalam database, maka mendaftarkan API baru hanya memerlukan satu tabel layanan dalam format:
CREATE TABLE DFM_PROC (
ID INTEGER NOT NULL,
NAME VARCHAR(70) NOT NULL,
DISCRIPTION VARCHAR(1000)
);
Sebagai contoh:
Skemanya adalah sebagai berikut:
Di sini kita akan mempertimbangkan bagaimana mengatur kerja dari layanan mikro "Layanan untuk antarmuka". Saya akan memberikan
contoh frontend di php
function ser1($proc_id,$json)
{
//
$post='hash='.$_SESSION['sess_id'].'&user_id='.$_SESSION['id_user'].'&proc_id='.$proc_id.'&json='.base64_encode($json);
//
$url = 'http://192.168.128.1/ser.php';
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST , true);
curl_setopt($ch, CURLOPT_POSTFIELDS ,$post);
$result = curl_exec($ch);
$arr_res=json_decode($result,true);
curl_close($ch);
return $arr_res;
}
//
//
// 4 -
if (isset($_POST['go_new_prof']))
{
unset($arr);
$arr['0']=$_SESSION['id_user'];
$arr['1']=(int)$_GET['tp'];
$arr['2']=(int)$_POST['lang_list'];
$arr_prof=ser1(4,json_encode($arr));
}
Contoh dari prosedur yang disebut di SQL
create or alter procedure DFM_PROF_ADD (
USER_ID smallint,
TYPE_ varchar(10),
LANG smallint)
as
begin
INSERT INTO DFM_PROFILES (USER_ID, TYPE_, LANG)
VALUES (:USER_ID, :TYPE_, :LANG);
suspend;
end
Sekarang kami memahami bagaimana mikroservice-relay akan memahami bahwa perlu untuk melakukan prosedur khusus ini, bagaimana ia akan memahami parameter apa yang dimilikinya, bagaimana ia akan menariknya. Saya akan memberikan contoh kode, detail di komentar di kode
<?php
$proc_id=(int)$_POST['proc_id'];
$json= base64_decode($_POST['json']);
$arr_json = json_decode($json,true);
// JSON
switch (json_last_error()) {
case JSON_ERROR_NONE:
$err = null;
break;
case JSON_ERROR_DEPTH:
$err = ' ';
break;
case JSON_ERROR_STATE_MISMATCH:
$err = ' ';
break;
case JSON_ERROR_CTRL_CHAR:
$err = ' ';
break;
case JSON_ERROR_SYNTAX:
$err = ' , JSON';
break;
case JSON_ERROR_UTF8:
$err = ' UTF-8, ';
break;
default:
$err = ' ';
break;
}
// JSON
if ($err==null)
{
// ID
$user_id=1;
// ID
$sql_proc = "select p.name from DFM_PROC p where p.id=".$proc_id;
$res_proc = ibase_query($dbh, $sql_proc);
$prom_proc = ibase_fetch_row($res_proc);
//
$sql_in='select ';
// ,
// RDB$PROCEDURE_PARAMETERS
$sql = 'select pp.rdb$parameter_number, pp.rdb$parameter_name from DFM_PROC p
left join RDB$PROCEDURE_PARAMETERS pp on pp.rdb$procedure_name=UPPER(p.name)
where p.id='.$proc_id.' and pp.rdb$parameter_type=1 --
order by pp.rdb$parameter_number';
$res = ibase_query($dbh, $sql);
$i_cou_out=0;
while($prom = ibase_fetch_row($res))
{
//p. -
$i_cou_out++;
if ($prom[0]>0) $sql_in.=',';
$sql_in.='p.'.$prom[1];
$name_out[$prom[0]]=$prom[1];
}
// -
$sql_in.=' from '.$prom_proc[0];
// , , execute procedure
if ($i_cou_out==0) $sql_in='execute procedure '.$prom_proc[0];
//
$sql = 'select
pp.rdb$parameter_number,
pp.rdb$parameter_name,
case
when f.rdb$field_type=7 then 1 --smalint
when f.rdb$field_type=8 then 2 --integer
when f.rdb$field_type=16 and f.rdb$field_scale=0 then 3 --bigint
when f.rdb$field_type=16 and f.rdb$field_scale<0 then 4 --frloat
when f.rdb$field_type=12 then 5 --date
when f.rdb$field_type=13 then 6 --time
when f.rdb$field_type=35 then 7 --timestamp
when f.rdb$field_type=37 then 8 --varcahr
end,
f.rdb$field_type, --
f.rdb$character_length, --
f.rdb$field_precision, --
f.rdb$field_scale --
from DFM_PROC p
left join RDB$PROCEDURE_PARAMETERS pp on pp.rdb$procedure_name=UPPER(p.name)
left join RDB$FIELDS f on f.rdb$field_name=pp.rdb$field_source
where p.id='.$proc_id.' and pp.rdb$parameter_type=0 --
order by pp.rdb$parameter_number';
$res = ibase_query($dbh, $sql);
$i_cou=0;
while($prom = ibase_fetch_row($res))
{
$i_cou++;
if ($prom[0]>0) $sql_in.=','; else $sql_in.='(';
if (($prom[2]==5)or($prom[2]==6)or($prom[2]==7)or($prom[2]==8))
//
// null
if ($arr_json[$prom[0]]=='')
$sql_in.="null";
else
$sql_in.="'".($arr_json[$prom[0]])."'";
else
//
if ($arr_json[$prom[0]]=='')
$sql_in.="null";
else
$sql_in.=($arr_json[$prom[0]]);
}
//
if ($i_cou_out==0)
{if ($i_cou>0) $sql_in.=')';}
else
{if ($i_cou>0) $sql_in.=') p'; else $sql_in.=' p';}
// p.
//
$res_in = ibase_query($dbh, $sql_in);
if ($i_cou_out==0)
{
// execute procedure
$json_out='{
"error_json":"",
"error_code_json":"",
"result":" execute procedure",
"result_code":0
}';
}
else
{
// json
$i_json=0;
$json_out='{';
while($prom_in = ibase_fetch_row($res_in))
{
if ($i_json>0) $json_out.=',';
$json_out.='"'.$i_json.'":{';
foreach($prom_in as $k => $v)
{
if ($k>0) $json_out.=',
';
$json_out.='"'.trim($name_out[$k]).'":"'.$v.'"';
}
$json_out.='}';
$i_json++;
}
$json_out.='}';
}
// - , ,
if (ibase_errmsg()=='')
{
//
echo $json_out;
}
else
{
//
$err_json='{
"error_json":"'.$err.'",
"error_code_json":'.json_last_error().',
"result":"'.str_replace('"','\'',ibase_errmsg()).'",
"result_code":2,
"sql_err":"'.$sql_in.'"}';
echo $err_json;
}
}
else
{
// JSON
$err_json='{
"error_json":"'.$err.'",
"error_code_json":'.json_last_error().',
"result":" json",
"result_code":3
}';
echo $err_json;
}
?>
Apa yang kita dapatkan pada akhirnya.
1) Kami menulis relai layanan mikro 1 kali. Semua desain arsitektur backend lainnya dilakukan di database. Di PHP (atau Go, Python, apa layanan mikro nantinya) kita tidak lagi mendaki.
Misalnya, fitur baru diperlukan di situs - frontend sedang dilakukan, prosedur sedang dilakukan. Prosedurnya didaftarkan di pelat dan bagian depan dengan nomor registrasinya memanggil API layanan mikro. SEGALA SESUATU.
Saya sarankan untuk menulis relai layanan mikro di Go sebagaimana telah dikompilasi dan jauh lebih cepat. Keunggulannya hanya perlu ditulis sekali dan programnya tidak ribet. Selain itu, ini akan menjadi elemen yang sangat dimuat, tempat panggilan intensif terjadi.
Library untuk menghubungkan firebird ke goland: https://github.com/nakagami/firebirdsql .
2) Semua pemrosesan masuk ke dalam prosedur - kita mendapatkan elemen yang dikompilasi yang memproses segala sesuatu di tingkat database dan menghasilkan HASIL. Itu. jika operasi terdiri dari beberapa pilih, masukkan, perbarui, dll. kami tidak mengarahkan data melalui jaringan ke backend, tetapi segera memprosesnya di database.
Ditambah prosedur adalah elemen yang dikompilasi dengan rencana kueri yang dihasilkan. Tidak ada sumber daya yang dihabiskan untuk ini juga.
3) Microservice-relay, untuk membentuk prosedur, mengacu pada database sebanyak 4 kali.
1. Dapatkan namanya
2. Dapatkan parameter keluarnya
3. Dapatkan parameter
masuknya 4. Jalankan prosedurnya
4 kali, karena kami menganggap metode universal. Ini bisa dikurangi menjadi sekali.
Caranya:
1. Dapat disimpan secara lokal di editor teks di server web misalnya. Cukup tarik tabel ini secara berkala dan perbarui ketika tabel baru ditambahkan.
2.3. Demikian juga, Anda dapat menyimpannya secara lokal dengan menariknya ke mana-mana ketika ada sesuatu yang diperbarui.
4) Tidak semua backend bisa dilakukan di database! Ini adalah bagian penting dari segalanya, tetapi seseorang harus dipandu oleh pertimbangan kemanfaatan .
Misalnya, beberapa obrolan, surat, dll. aspek kehidupan layanan web, tentu saja, harus dilakukan sebagai layanan mikro terpisah dalam bahasa pemrograman yang paling nyaman untuk ini. Tidak perlu mentransfer semua logika layanan web ke pangkalan dengan biaya berapa pun! Anda hanya perlu mentransfer bagian yang nyaman untuk ini!