துறை

சேவையகம் — HTTP, தரவுத்தளங்கள், அங்கீகாரம்

இ-தமிழ் பின்தளச் சேவைகளை இயக்குகிறது: வழிச்செலுத்தலுடன் கூடிய HTTP சேவையகம், அளபுரு வினாக்கள் மட்டுமே அனுமதிக்கும் SQLite மற்றும் PostgreSQL இயக்கிகள், JSON, bcrypt, JWT.

இ-தமிழ் ஒரு பின்தள மொழி. ஒரு நிரல் HTTP வழங்க, SQL தரவுத்தளத்துடன் பேச, கடவுச்சொற்களை மறையாக்க, டோக்கன்களை வழங்க முடியும் — Rust-க்குள் இறங்காமல்.

HTTP சேவையகம்

etamil --server --port 8080 examples/backend/hello_server.qmz
etamil --async  --port 8080 examples/backend/hello_server.qmz

--server ஒரு பணியாளர் குழுவை இயக்குகிறது. --async ஒரு tokio ஏற்பு சுழற்சியை இயக்கி ஒவ்வொரு கோரிக்கையையும் தடுப்புக் குழுவுக்கு அனுப்புகிறது; எனவே ஒரு இணைப்பு ஒரு நூலுக்குப் பதிலாக ஒரு பணியாக மட்டுமே செலவாகிறது, மேலும் மெதுவான வாடிக்கையாளர் ஒருவர் தன் கோரிக்கையை அனுப்ப எடுக்கும் நேரம் முழுவதும் 2 × cores பணியாளர்களில் ஒருவரை ஆக்கிரமிப்பதில்லை. VM ஒத்திசைவானதாகவே இருக்கிறது — கையாளிகள் tokio-வின் தடுப்புக் குழுவில் தடுக்கின்றன; எனவே ஒவ்வொரு தரவுத்தள இயக்கியும் தொடாமலேயே தொடர்ந்து இயங்குகிறது.

வழிகள்

வழி ஒரு வழியை அறிவிக்கிறது; பதில் பதிலளிக்கிறது.

வழி பெறு, "/kaNakku/:id" {
    பதில் 200, "id=" & param_id & " vakY=" & query_params["vakY"];
}

வழி பதி, "/pativu" {
    பதில் 201, "got body: " & request_body;
}

வழி பெறு, "/aRikkY.csv" {
    பதில் 200, வரிசைகள், {"Content-Type": "text/csv"};
}

ஒரு கையாளி தன் கோரிக்கையை சாதாரண மாறிகள் வழியாகப் படிக்கிறது; எனவே அதே கையாளி எந்த எழுத்து வடிவத்திலும் படிக்கக்கூடியதாக இருக்கிறது:

மாறி உள்ளடக்கம்
request_method HTTP முறை
request_path கோரப்பட்ட பாதை
request_body மூல உடல்
query_params வினாச் சரம், ஒரு பதிவேடாக
headers கோரிக்கைத் தலைப்புகள், ஒரு பதிவேடாக
path_params பொருந்திய :name பகுதிகள், ஒரு பதிவேடாக
param_<name> ஒவ்வொரு பாதை அளபுருவும், நேரடியாகவும்

பதில் தலைப்புகள் ஒரு சாதாரண பதிவேடு. அது இல்லாதபோது சேவையகம் application/json எனப் பதிலளிக்கிறது.

கொடி விளைவு
--vm பைட்கோட் VM-இல் இயக்கு (இயல்பு)
--check லெக்ஸ், பாகுபடுத்தல், வகைச் சரிபார்ப்பு மட்டும் செய்து நிற்கும் — அனைத்துப் பிழைகளையும் தெரிவிக்கும், நிரலை ஒருபோதும் இயக்காது
--server ஒத்திசைவான HTTP சேவையகத்தைத் தொடங்கு
--async ஒருங்கிணைந்த சேவையகம்: async ஏற்பு, தடுப்புக் கையாளிகள், நிறுத்த Ctrl-C
--llvm LLVM பின்தளம் (--features llvm தேவை; Linux/macOS)
--port <PORT> சேவையகத் துறை (இயல்பு 8080)
--host <HOST> சேவையக முகவரி (இயல்பு 127.0.0.1)

தரவுத்தளங்கள்

வினாக்கள் எப்போதும் அளபுருவாக்கப்பட்டவை. இ-தமிழிலிருந்து SQL உரையில் ஒரு மதிப்பைச் செருக வேண்டுமென்றே எந்த வழியும் இல்லை; எனவே ஊடுருவல் (injection) வகைப் பிழையை எழுதவே முடியாது.

தளம்_இணை எசுகியூஎல்லைட், "kaNakku.db";
தளம்_வினா "SELECT peyar, qokY FROM pativukaL WHERE vakY = ?", ["வரவு"], வரவுகள்;

வரிசைகள் பதிவேடுகளின் அணியாகத் திரும்புகின்றன; எனவே ஒரு முடிவுத் தொகுப்பு வேறு எந்த அட்டவணையையும் போலவே சுழல்கிறது.

இயந்திரம் நிலை குறிப்புகள்
SQLite இயங்குகிறது உள்ளமைக்கப்பட்டது, வசதிக் கொடி தேவையில்லை. தசமங்கள் உரையாகக் கடக்கின்றன; எனவே துல்லியம் இழக்கப்படுவதில்லை
PostgreSQL இயங்குகிறது --features postgres; நேரடி சேவையகத்தில் சரிபார்க்கப்பட்டது. பணம் சொந்த NUMERIC வகையைப் பயன்படுத்துகிறது
MySQL / MariaDB நேரடியாகச் சரிபார்க்கப்பட்டது --features mysql; ETAMIL_TEST_MYSQL=1 ./scripts/run_examples.sh மூலம் நேரடி மாதிரி தேர்ச்சி பெறுகிறது. அமைவு விவரங்கள் TESTING.md-இல்
MongoDB இயங்குகிறது --features mongodb. இது Database trait வழியே செல்லவில்லை, செல்லவும் கூடாது: ஒரு ஆவணம் ஒரு பொருள்ஏ — எனவே எண்களில் கவனம் (Decimal128, double அல்ல) மட்டுமே தேவைப்பட்டது
Redis இயங்குகிறது இதுவும் trait-க்கு வெளியே, அதே காரணத்தால்: Redis ஒரு கட்டளையும் பதிலும் — எனவே ஹோஸ்ட் ஒரே பொதுவான ரெடிஸ்_கட்டளை தருகிறது, எல்லாக் கட்டளைகளும் இயங்குகின்றன
cargo build --release --features postgres,mysql

PostgreSQL இடங்காட்டிகள் $1, $2, …; SQLite மற்றும் MySQL ? ஐப் பயன்படுத்துகின்றன.

தளம்_இணை போச்குரசீகுல், "postgres://user:pass@localhost:5432/kaNakku";
தளம்_வினா "SELECT peyar, qokY FROM pativukaL WHERE vakY = $1", ["வரவு"], வரவுகள்;

இரு சேவையகப் பின்தளங்களும் பணத்தைத் தரவுத்தளத்தின் சொந்தத் துல்லிய தசம வகையில் வைக்கின்றன; எனவே ஒரு உரை நெடுவரிசை திரும்பும்போதும் உரையாகவே இருக்கிறது — தசமங்களை உரையாகச் சேமிக்கும் SQLite பின்தளம் ஒரு எண்ணைத் திருப்பும் இடத்தில். PostgreSQL மேற்கோளிடப்படாத அடையாளங்காட்டிகளைச் சிறிய எழுத்துக்கு மாற்றுகிறது: நீங்கள் எழுதியபடியே நெடுவரிசைப் பெயர் திரும்ப வேண்டுமெனில் "qokY" என எழுதுங்கள்.

இன்னும் செய்ய வேண்டியவை. பரிவர்த்தனைகள், மற்றும் ஒரே நேரத்தில் ஒன்றுக்கு மேற்பட்ட இணைப்புகள் — நீங்கள் எதைக் குறிப்பிட்டீர்கள் என ஊகிப்பதற்குப் பதிலாக VM தற்போது இரண்டாவதை மறுக்கிறது.

JSON

jEcAZ.qmz ஹோஸ்டில் அல்ல, இ-தமிழிலேயே எழுதப்பட்டுள்ளது. ஒரு JSON பாகுபடுத்திக்குத் தரவிலிருந்து வரும் புலப் பெயர்களைக் கொண்ட பதிவேட்டை உருவாக்க வேண்டும்; VM அதை ஏற்கெனவே அனுமதிக்கிறது: பொருள்[சாவி] = மதிப்பு சாவியை இயக்க நேரத்தில் கணக்கிடுகிறது.

இறக்கு "nUlakam/jEcAZ.qmz";

ப = மதிப்பு(ஜேசான்_படி(request_body));
அச்சு ப["qokY"] + 1;                       // ஒரு எண், உரை அல்ல
பதில் 200, ஜேசான்_ஆக்கு({நிலுவை: 1500});

ஜேசான்_படி சரி/தவறு திருப்புகிறது; எனவே தவறான உள்ளீடு ஊகிக்கப்படாமல் கையாளப்படுகிறது. பதிவேட்டுப் புலங்கள் வரிசைப்படுத்தப்பட்ட ஒழுங்கில் தொடராக்கப்படுகின்றன; இது ஒரு பதில் உடலை உறுதிப்படுத்தத்தக்க அளவுக்கு நிலையானதாக்குகிறது. \uXXXX விடுபடல்கள் மாற்றப்படுவதில்லை.

ஜேசான்_உரை செயல்படுத்தப்படவில்லை. அது பாகுபடுத்தப்படுகிறது, ஆனால் VM அதை மறுக்கிறது. உடலை ஜேசான்_ஆக்கு மூலம் உருவாக்கி பதில் மூலம் அனுப்புங்கள்.

பிற சேவைகளை அழைத்தல்

வலை_பெறு, வலை_பதி, வலை_அனுப்பு ஆகியவை வெளிச்செல்லும் HTTP கோரிக்கைகளை அனுப்புகின்றன; --features http-client பின்னால், அது இயல்பாகவே இயக்கத்தில் உள்ளது. 2xx அல்லாத பதில் ஒரு தோல்வியாக அல்லாமல் சாதாரண முடிவாகவே திரும்புகிறது; எனவே கட்டணச் சேவையிலிருந்து வரும் 404 என்பது நீங்கள் கிளைபிரித்துக் கையாள வேண்டியது, உங்கள் கையாளியை நிறுத்துவது அல்ல.

ப = வலை_பெறு("https://api.example.in/rates");
(சரியா(ப)) எனில் {
    அச்சு மதிப்பு(ப).உடல்;
}

கையொப்பமிடலும் வெப்ஹூக் சரிபார்ப்பும்

கையொப்பம் HMAC-SHA256 கையொப்பத்தை உருவாக்குகிறது; கையொப்பம்_சரியா ஒன்றைச் சரிபார்க்கிறது. ஒப்பீடு நிலையான நேரத்தில் நடக்கிறது; எனவே சரிபார்ப்பு எவ்வளவு நேரம் எடுத்தது என்பதை அளக்கும் எவருக்கும் எதிர்பார்க்கப்படும் கையொப்பத்தை ஒவ்வொரு பைட்டாகக் கசியவிடுவதில்லை.

வழி பதி, "/webhook" {
    (கையொப்பம்_சரியா(request_body, headers["X-Signature"], ரகசியம்)) எனில் {
        பதில் 200, "ok";
    }
    பதில் 401, "bad signature";
}

பைட்டுகள், base64, hex

பைட்டுகள் உரையைப் பைட்டுகளாக மாற்றுகிறது; பைட்டுச்_சரம் மீண்டும் உரையாக்குகிறது. ஒரு பைட் அணி என்பது எண்களின் சாதாரண அணியே — வேண்டுமென்றே புதிய மதிப்பு வகை அல்ல; எனவே nUlakam/aNi.qmz-இல் உள்ள ஒவ்வொரு அணிச் செயலும் அதன் மீது ஏற்கெனவே வேலை செய்யும்.

குறியாக்கம் nUlakam/kuRiyAkkam.qmz-இல் உள்ளது, மற்றவை போலவே இ-தமிழில் எழுதப்பட்டது: base64-க்கு அறுபத்துநான்கு_ஆக்கு, அறுபத்துநான்கு_படி; hex-க்கு பதினாறு_ஆக்கு, பதினாறு_படி.

திட்டமிட்ட பணிகள்

இடைவெளி ஒரு தொகுதியை இரு சேவையகங்களிலும் கால அட்டவணைப்படி இயக்குகிறது — சரிகட்டல் சுற்று, மறுமுயற்சி வரிசை, இரவு நிறைவு.

இடைவெளி 3600 {
    அச்சு "மணிநேர சரிகட்டல்";
}

அந்த எண் இயக்கங்களுக்கு இடையிலான இடைவெளி; நிலையான கால அளவு அல்ல. ஒரு இயக்கம் இடைவெளியை விட நீண்டால், அடுத்தது ஏற்கெனவே ஓடிக்கொண்டிருப்பதன் மேல் தொடங்காமல் தாமதமாகத் தொடங்குகிறது — பேரேட்டுப் பதிவுகளை இடும் ஒரு பணிக்கு, அது தாமதத்துக்கும் தவறுக்கும் இடையிலான வேறுபாடு.

அங்கீகாரம்

bcrypt மற்றும் JWT ஹோஸ்டில் உள்ளன; ஏனெனில் மறையாக்கத்துக்கும் HMAC-SHA256-க்கும் மொழியால் எட்ட முடியாத பைட்டுகளும் சமவாய்ப்பும் தேவை:

கடவுச்சொல்_மறை · கடவுச்சொல்_சரியா · சீட்டு_ஆக்கு · சீட்டு_சரிபார்

சேவையகத்தைத் தொடங்கும் முன் ETAMIL_JWT_SECRET ஐ அமைக்கவும். இந்த நான்குக்கும் மேலுள்ள அனைத்தும் — ஒரு பயனர் யார், எந்த வழிக்கு எந்தப் பங்கு தேவை — இ-தமிழிலேயே இருக்கின்றன; மேலும் ஒரு டோக்கனின் சுமை, jEcAZ.qmz படிக்கவும் எழுதவும் செய்யும் JSON உரையாக எல்லையைக் கடக்கிறது.

எடுத்துக்காட்டுகள்

etamil --server --port 8080 examples/backend/hello_server.qmz
etamil --server --port 8080 examples/backend/user_server.qmz
etamil --server --port 8080 examples/api/vari_cEvY.qmz
etamil --vm examples/db_samples/kaNakku_qaLam.qmz

examples/db_samples/mYcIkul_qaLam.qmz ஒரு உண்மையான MySQL சேவையகத்தில் சரிபார்க்கத் தகுந்தவற்றைச் சோதிக்கிறது — துல்லியமான DECIMAL கூட்டுத்தொகைகள், எண்ணிலிருந்து பிணைக்கப்பட்ட முழு எண் சாவி, ISO உரையாகத் தேதிகள், இன்மை ஆக NULL, மற்றும் செயலற்றுப் போகும் ஊடுருவல் சுமை. இதற்கு நேரடித் தரவுத்தளம் தேவை; எனவே நீங்கள் விரும்பினால் அன்றி எடுத்துக்காட்டு இயக்கி அதைத் தவிர்க்கிறது:

ETAMIL_TEST_MYSQL=1 ./scripts/run_examples.sh