View Source PhxJsonRpc (Phoenix JSON RPC v0.6.0)

A simple implementation of the JSON-RPC.

JSON-RPC is a remote procedure call protocol encoded in JSON. It is similar to the XML-RPC protocol, defining only a few data types and commands.

JSON-RPC allows for notifications (data sent to the server that does not require a response) and for multiple calls to be sent to the server which may be answered asynchronously.

Getting started

Add :phx_json_rpc to your dependencies

{:phx_json_rpc, "~> 0.6.0"}

Usage with phoenix

  1. Prepare your service specification, written as JSON SCHEMA

    The bunch of examples can be found here.

    Usually it should be stored as a dependency or just a file in your repo (for ex myapp/priv/static/openrpc.json).

  2. Configure rpc router, specifying json schema version and batch size params

defmodule MyApp.Rpc.Router do
  use PhxJsonRpc.Router,
    otp_app: :rpc_router,
    schema: "[PATH_TO_YOUR_SCHEMA]",
    version: "2.0",
    max_batch_size: 20

  alias MyAppRpc.PetController

  ## Middleware group (optional)
  # Uncomment the line below, when neccessary (see `PhxJsonRpc.Router.Middleware` for usage)
  # middleware([AuthMiddleware])

  ## Pet's service
  rpc("pet.create", PetController, :create, "#/components/schemas/Pet")
  rpc("pet.list", PetController, :list, "#/components/schemas/Pets")
  rpc("pet.update", PetController, :update, "#/components/schemas/Pet")
  rpc("pet.delete", PetController, :delete, "#/components/schemas/PetId")
end
  1. Specify service module
defmodule MyAppRpc.PetController do
  @moduledoc "My Pet Service"

  def create(%{"name" => name}, context) do
    "Created"
  end

  def list(_params, context) do
    [
      "Cat",
      "Dog"
    ]
  end

  def update(params, context) do
    "Update your pet here"
  end

  def delete(%{"id" => id}, context) do
    "Pet removed from the store"
  end
end
  1. Create controller for handling requests via http
defmodule MyAppWeb.RpcController do
  use MyAppWeb, :controller

  alias MyApp.Rpc.Router

  def rpc(conn, request) do
    # Handles rpc requests
    # The second parameter is optional and used to share current context
    response = Router.handle(request, conn)
    render(conn, "response.json", response)
  end
end
  1. Import helpers inside your view and define render function
defmodule MyAppWeb.RpcView do
  use MyAppWeb, :view

  import PhxJsonRpc.Views.Helpers

  def render("response.json", %{response: response}) do
    render_json(response)
  end
end

Optionally, you can import PhxJsonRpc.Views.Helpers inside the view_helpers quote block in your web.ex like so:

  defp view_helpers do
    quote do
      ...

      import PhxJsonRpcWeb.Views.Helpers
    end
  end
  1. Add endpoint path to your phoenix router under the api scope
scope "/api", MyAppWeb do
  pipe_through :api

  post("/rpc", RpcController, :rpc)
end
  1. Start phoenix server and make an http request
curl -X POST    -H 'Content-Type:application/json'    -d '{"jsonrpc":"2.0","id":"[ID]","method":"pet.create","params":{"name":"Kitty"}}'    http://localhost:4000/api/rpc

Request and response using postman:

request

response