SOA (Arsitektur Berorientasi Layanan) dibangun dengan menggabungkan dan berinteraksi dengan layanan yang digabungkan secara longgar.Untuk menunjukkan, kami akan membuat dua aplikasi, Client dan Server, dan mengatur interaksi mereka menggunakan protokol panggilan prosedur jarak jauh JSON-RPC 2.0
.Pelanggan
Aplikasi Klien adalah situs untuk membuat dan menampilkan konten tertentu. Klien tidak mengandung database sendiri, tetapi menerima dan menambahkan data karena interaksi dengan aplikasi Server.Pada klien, interaksi menyediakan kelasJsonRpcClient
namespace ClientApp\Services;
use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;
class JsonRpcClient
{
const JSON_RPC_VERSION = '2.0';
const METHOD_URI = 'data';
protected $client;
public function __construct()
{
$this->client = new Client([
'headers' => ['Content-Type' => 'application/json'],
'base_uri' => config('services.data.base_uri')
]);
}
public function send(string $method, array $params): array
{
$response = $this->client
->post(self::METHOD_URI, [
RequestOptions::JSON => [
'jsonrpc' => self::JSON_RPC_VERSION,
'id' => time(),
'method' => $method,
'params' => $params
]
])->getBody()->getContents();
return json_decode($response, true);
}
}
Kami membutuhkan perpustakaan GuzzleHttp
, pra-instal.Kami membentuk POST
permintaan yang sepenuhnya standar menggunakan GuzzleHttp\Client
. Peringatan utama di sini adalah format permintaan.Menurut spesifikasi, JSON-RPC 2.0
permintaan akan terlihat seperti:{
"jsonrpc": "2.0",
"method": "getPageById",
"params": {
"page_uid": "f09f7c040131"
},
"id": "54645"
}
jsonrpc
versi protokol, harus menunjukkan "2.0"method
nama metodeparams
array dengan parameterid
meminta id
Menjawab{
"jsonrpc": "2.0",
"result": {
"id": 2,
"title": "Index Page",
"content": "Content",
"description": "Description",
"page_uid": "f09f7c040131"
},
"id": "54645"
}
Jika permintaan selesai dengan kesalahan, kami mendapatkannya{
"jsonrpc": "2.0",
"error": {
"code": -32700,
"message": "Parse error"
},
"id": "null"
}
jsonrpc
versi protokol, harus menunjukkan "2.0"result
bidang wajib untuk hasil kueri yang sukses. Seharusnya tidak ada saat kesalahan terjadierror
bidang wajib diisi saat terjadi kesalahan. Seharusnya tidak ada pada hasil yang suksesid
pengidentifikasi permintaan yang ditetapkan oleh klien
Server membentuk jawabannya, jadi kami akan kembali ke sana.Di controller, perlu untuk membuat permintaan dengan parameter yang diperlukan dan memproses respons.namespace ClientApp\Http\Controllers;
use App\Services\JsonRpcClient;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
class SiteController extends Controller
{
protected $client;
public function __construct(JsonRpcClient $client)
{
$this->client = $client;
}
public function show(Request $request)
{
$data = $this->client->send('getPageById', ['page_uid' => $request->get('page_uid')]);
if (empty($data['result'])) {
abort(404);
}
return view('page', ['data' => $data['result']]);
}
public function create()
{
return view('create-form');
}
public function store(Request $request)
{
$data = $this->client->send('create', $request->all());
if (isset($data['error'])) {
return Redirect::back()->withErrors($data['error']);
}
return view('page', ['data' => $data['result']]);
}
}
Format respons tetap JSON-RPC memudahkan untuk melihat apakah permintaan itu berhasil dan mengambil tindakan apa pun jika responsnya mengandung kesalahan.Server
Mari kita mulai dengan mengatur perutean. Dalam file routes/api.php
addRoute::post('/data', function (Request $request, JsonRpcServer $server, DataController $controller) {
return $server->handle($request, $controller);
});
Semua permintaan yang diterima oleh server di alamat <server_base_uri>/data
akan diproses oleh kelasJsonRpcServer
namespace ServerApp\Services;
class JsonRpcServer
{
public function handle(Request $request, Controller $controller)
{
try {
$content = json_decode($request->getContent(), true);
if (empty($content)) {
throw new JsonRpcException('Parse error', JsonRpcException::PARSE_ERROR);
}
$result = $controller->{$content['method']}(...[$content['params']]);
return JsonRpcResponse::success($result, $content['id']);
} catch (\Exception $e) {
return JsonRpcResponse::error($e->getMessage());
}
}
}
Kelas JsonRpcServer
mengikat metode pengontrol yang diinginkan dengan parameter yang dikirimkan. Dan mengembalikan respons yang dihasilkan oleh kelas JsonRpcResponse
dalam format sesuai dengan spesifikasi yang JSON-RPC 2.0
dijelaskan di atas.use ServerApp\Http\Response;
class JsonRpcResponse
{
const JSON_RPC_VERSION = '2.0';
public static function success($result, string $id = null)
{
return [
'jsonrpc' => self::JSON_RPC_VERSION,
'result' => $result,
'id' => $id,
];
}
public static function error($error)
{
return [
'jsonrpc' => self::JSON_RPC_VERSION,
'error' => $error,
'id' => null,
];
}
}
Tetap menambahkan pengontrol.namespace ServerApp\Http\Controllers;
class DataController extends Controller
{
public function getPageById(array $params)
{
$data = Data::where('page_uid', $params['page_uid'])->first();
return $data;
}
public function create(array $params)
{
$data = DataCreate::create($params);
return $data;
}
}
Saya tidak melihat alasan untuk menggambarkan pengontrol secara detail, metode yang cukup standar. Kelas DataCreate
berisi semua logika membuat objek, serta memeriksa validitas bidang dengan melempar pengecualian yang diperlukan.Kesimpulan
Saya mencoba untuk tidak mempersulit logika aplikasi itu sendiri, tetapi untuk fokus pada interaksi mereka.Pro dan kontra JSON-RPC ditulis dengan baik dalam sebuah artikel, tautan yang akan saya tinggalkan di bawah. Pendekatan ini relevan, misalnya, ketika menerapkan formulir yang disematkan.Referensi