рд▓рд╛рд░рд╛рд╡реЗрд▓ рдФрд░ JSON-RPC 2.0 рдкрд░ SOA

SOA (рд╕рд░реНрд╡рд┐рд╕ рдУрд░рд┐рдПрдВрдЯреЗрдб рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░) рдХрд╛ рд╕рдВрдпреЛрдЬрди рдФрд░ рдвреАрд▓реА рдХрдкрд▓ рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рдкрд░рд╕реНрдкрд░ рдХреНрд░рд┐рдпрд╛ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рджреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди, рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░ рдмрдирд╛рдПрдВрдЧреЗ рдФрд░ рджреВрд░рд╕реНрде рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЙрд▓ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрдирдХреА рд╕рд╣рднрд╛рдЧрд┐рддрд╛ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░реЗрдВрдЧреЗ JSON-RPC 2.0ред

рдЧреНрд░рд╛рд╣рдХ


рдХреНрд▓рд╛рдЗрдВрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреБрдЫ рд╕рд╛рдордЧреНрд░реА рдмрдирд╛рдиреЗ рдФрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдЗрдЯ рд╣реИред рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдкрд╛рд╕ рд╕реНрд╡рдпрдВ рдХрд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд░реНрд╡рд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХреЗ рдХрд╛рд░рдг рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЬреЛрдбрд╝рддрд╛ рд╣реИред

рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд░, рдЗрдВрдЯрд░реИрдХреНрд╢рди рдПрдХ рд╡рд░реНрдЧ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИJsonRpcClient

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);
    }
}

рд╣рдореЗрдВ рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ GuzzleHttp, рдЗрд╕реЗ рдкреВрд░реНрд╡-рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВред
рд╣рдо рдПрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдорд╛рдирдХ POSTрдЕрдиреБрд░реЛрдз рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ GuzzleHttp\Clientред рдпрд╣рд╛рдБ рдореБрдЦреНрдп рдЪреЗрддрд╛рд╡рдиреА рдЕрдиреБрд░реЛрдз рдкреНрд░рд╛рд░реВрдк рд╣реИред
рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рдХреЗ рдЕрдиреБрд╕рд╛рд░, JSON-RPC 2.0рдЕрдиреБрд░реЛрдз рдХреЛ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП:

{
    "jsonrpc": "2.0", 
    "method": "getPageById",
    "params": {
        "page_uid": "f09f7c040131"
    }, 
    "id": "54645"
}

  • jsonrpc рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╕рдВрд╕реНрдХрд░рдг, "2.0" рдЗрдВрдЧрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
  • method рд╡рд┐рдзрд┐ рдХрд╛ рдирд╛рдо
  • params рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд░рдгреА
  • id рдЕрдиреБрд░реЛрдз рдЖрдИрдбреА

рдЙрддреНрддрд░

{
    "jsonrpc": "2.0",
    "result": {
        "id": 2,
        "title": "Index Page",
        "content": "Content",
        "description": "Description",
        "page_uid": "f09f7c040131"
    },
    "id": "54645"
}

рдпрджрд┐ рдЕрдиреБрд░реЛрдз рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЗ рд╕рд╛рде рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рдерд╛, рддреЛ рд╣рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ

{
    "jsonrpc": "2.0",
    "error": {
        "code": -32700,
        "message": "Parse error"
    },
    "id": "null"
}

  • jsonrpc рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╕рдВрд╕реНрдХрд░рдг, "2.0" рдЗрдВрдЧрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
  • resultрдПрдХ рд╕рдлрд▓ рдХреНрд╡реЗрд░реА рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдлрд╝реАрд▓реНрдбред рддреНрд░реБрдЯрд┐ рд╣реЛрдиреЗ рдкрд░ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП
  • errorрдЖрд╡рд╢реНрдпрдХ рдлрд╝реАрд▓реНрдб рдЬрдм рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИред рд╕рдлрд▓ рдкрд░рд┐рдгрд╛рдо рдкрд░ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП
  • id рдЧреНрд░рд╛рд╣рдХ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдЕрдиреБрд░реЛрдз

рд╕рд░реНрд╡рд░ рдЙрддреНрддрд░ рдмрдирд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрд╕рдореЗрдВ рд╡рд╛рдкрд╕ рдЖрдПрдВрдЧреЗред

рдирд┐рдпрдВрддреНрд░рдХ рдореЗрдВ, рдЖрд╡рд╢реНрдпрдХ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдЕрдиреБрд░реЛрдз рдмрдирд╛рдиреЗ рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред

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']]);
    }
}

JSON-RPC рдирд┐рд╢реНрдЪрд┐рдд рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕реНрд╡рд░реВрдк рдпрд╣ рджреЗрдЦрдиреЗ рдореЗрдВ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЕрдиреБрд░реЛрдз рд╕рдлрд▓ рд░рд╣рд╛ рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реЛрдиреЗ рдкрд░ рдХреЛрдИ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░реЗрдВред

рд╕рд░реНрд╡рд░


рдЪрд▓реЛ рд░реВрдЯрд┐рдВрдЧ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдХреЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдлрд╝рд╛рдЗрд▓ routes/api.phpрдРрдб рдореЗрдВ

Route::post('/data', function (Request $request, JsonRpcServer $server, DataController $controller) {
    return $server->handle($request, $controller);
});

рдкрддреЗ рдкрд░ рд╕рд░реНрд╡рд░ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╛рдкреНрдд рд╕рднреА рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ <server_base_uri>/dataрдХрдХреНрд╖рд╛ рджреНрд╡рд╛рд░рд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛JsonRpcServer

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());
        }
    }
}

рдХрдХреНрд╖рд╛ JsonRpcServerрдЙрддреНрддреАрд░реНрдг рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рд╡рд╛рдВрдЫрд┐рдд рдирд┐рдпрдВрддреНрд░рдХ рд╡рд┐рдзрд┐ рдХреЛ рдмрд╛рдВрдзрддреА рд╣реИред рдФрд░ рдпрд╣ рдКрдкрд░ рд╡рд░реНрдгрд┐рдд JsonRpcResponseрд╡рд┐рдирд┐рд░реНрджреЗрд╢ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рд╡рд░реНрдЧ рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрддрд╛ JSON-RPC 2.0рд╣реИред

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,
        ];
    }
}

рдпрд╣ рдПрдХ рдирд┐рдпрдВрддреНрд░рдХ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╣рддрд╛ рд╣реИред

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;
    }
}

рдореБрдЭреЗ рдирд┐рдпрдВрддреНрд░рдХ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ, рдХрд╛рдлреА рдорд╛рдирдХ рддрд░реАрдХреЗред рдХрдХреНрд╖рд╛ DataCreateрдореЗрдВ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд╕рднреА рддрд░реНрдХ рд╣реЛрддреЗ рд╣реИрдВ, рд╕рд╛рде рд╣реА рдЖрд╡рд╢реНрдпрдХ рдЕрдкрд╡рд╛рдж рдХреЗ рдлреЗрдВрдХрдиреЗ рдХреЗ рд╕рд╛рде рдЦреЗрддреЛрдВ рдХреА рд╡реИрдзрддрд╛ рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХреА рдЬрд╛рддреА рд╣реИред

рдирд┐рд╖реНрдХрд░реНрд╖


рдореИрдВрдиреЗ рд╕реНрд╡рдпрдВ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рддрд░реНрдХ рдХреЛ рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рд▓реЗрдХрд┐рди рдЙрдирдХреА рдмрд╛рддрдЪреАрдд рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд┐рдпрд╛ред
JSON-RPC рдХреЗ рдкреЗрд╢реЗрд╡рд░реЛрдВ рдФрд░ рд╡рд┐рдкрдХреНрд╖реЛрдВ рдХреЛ рдПрдХ рд▓реЗрдЦ рдореЗрдВ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕рдХреА рдПрдХ рдХрдбрд╝реА рдореИрдВ рдиреАрдЪреЗ рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛ред рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдореНрдмреЗрдбреЗрдб рд░реВрдкреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╕рдордпред

рд╕рдВрджрд░реНрдн



All Articles