REST Client
Key takeaways
RestClient | Component used to call remote endpoints using the HTTP/REST protocol. |
RestService | Component used to receive remote calls via the HTTP/REST protocol. |
GET, HEAD, POST, PUT, DELETE | HTTP methods supported by the RestClient component. |
Introduction
A REST client is a program used to communicate with a service via the HTTP/REST protocol. Within Pip.Services, the RestClient component can be used as a base to build REST clients.
In this tutorial, you will be introduced to the RestClient component. First, we will see how to create a REST service by using the RestService class. Then, we will learn how to create a REST client with a class that extends the RestClient component. Following this, we will understand how to use the different HTML methods to communicate between the client and the service. We will end by reviewing what we learned in the different sections.
The REST service
Our first step is to create a REST service. For this, we create a subclass of the RestService class. To show the different HTTP communication methods, this subclass includes one function per HTTP method. Each of these functions returns a message and a data parameter. Our component also includes a register() method, which is used to register the route for each of the HTTP methods.
Once we have defined our REST service, we instantiate and configure it to run on our local machine. Then, we make it available with the open() method. The following code shows how this program looks like:
import { ConfigParams } from "pip-services3-commons-nodex";
import { RestService } from "pip-services3-rpc-nodex";
export class MyRestService extends RestService {
public constructor() {
super();
this._baseRoute = "/my_service";
}
// GET
public async myPageGet(req: any, res: any): Promise<void> {
let result = req.query.message + ", " + req.route.params.name;
this.sendResult(req, res, result);
}
// HEAD
public async myPageHead(req: any, res: any): Promise<void> {
this.sendResult(req, res, null);
}
// POST
public async myPagePost(req: any, res: any): Promise<void> {
let result = req.query.message + ", " + req.route.params.name + ", " + "data:" + req.body.data1;
this.sendResult(req, res, result);
}
// PUT
public async myPagePut(req: any, res: any): Promise<void> {
let result = req.query.message + ", " + req.route.params.name + ", " + "data:" + req.body.data1;
this.sendResult(req, res, result);
}
// Route registration
public register(): void {
this.registerRoute("GET", "/my_page/:name", null, this.myPageGet)
this.registerRoute("HEAD", "/my_page/:name", null, this.myPageHead)
this.registerRoute("POST", "/my_page/:name", null, this.myPagePost)
this.registerRoute("PUT", "/my_page/:name", null, this.myPagePut)
}
}
// Instantiation
let myRestService = new MyRestService();
// REST service configuration
myRestService.configure(ConfigParams.fromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15235
));
// Connection
await myRestService.open("123");
using PipServices3.Commons.Config;
using PipServices3.Rpc.Services;
class MyRestService : RestService
{
public MyRestService(): base()
{
_baseRoute = "/my_service";
}
// GET
private async Task MyPageGet(HttpRequest request, HttpResponse response, RouteData routeData)
{
var name = routeData.Values["name"].ToString();
var message = request.Query.TryGetValue("message", out StringValues sortValues)
? sortValues.ToString()
: string.Empty;
var res = message + ", " + name;
await this.SendResultAsync(response, res);
}
// HEAD
private async Task MyPageHead(HttpRequest request, HttpResponse response, RouteData routeData)
{
await this.SendEmptyResultAsync(response);
}
// POST
private async Task MyPagePost(HttpRequest request, HttpResponse response, RouteData routeData)
{
var name = routeData.Values["name"].ToString();
var message = request.Query.TryGetValue("message", out StringValues sortValues)
? sortValues.ToString()
: string.Empty;
IDictionary<string, object> data = null;
using (var streamReader = new StreamReader(request.Body))
{
data = JsonConverter.ToMap(streamReader.ReadToEnd());
}
var res = message + ", " + name + ", " + "data:" + data["data1"];
await this.SendResultAsync(response, res);
}
// PUT
private async Task MyPagePut(HttpRequest request, HttpResponse response, RouteData routeData)
{
var name = routeData.Values["name"].ToString();
var message = request.Query.TryGetValue("message", out StringValues sortValues)
? sortValues.ToString()
: string.Empty;
IDictionary<string, object> data = null;
using (var streamReader = new StreamReader(request.Body))
{
data = JsonConverter.ToMap(streamReader.ReadToEnd());
}
var res = message + ", " + name + ", " + "data:" + data["data1"];
await this.SendResultAsync(response, res);
}
}
// Instantiation
var myRestService = new MyRestService();
// REST service configuration
myRestService.Configure(ConfigParams.FromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15235
));
// Connection
await myRestService.OpenAsync("123");
import (
"context"
"net/http"
cconf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
cerr "github.com/pip-services3-gox/pip-services3-commons-gox/errors"
"github.com/pip-services3-gox/pip-services3-rpc-gox/services"
)
func main() {
// Instantiation
myRestService := NewMyRestService()
// REST service configuration
myRestService.Configure(context.Background(), cconf.NewConfigParamsFromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15235,
))
// Connection
myRestService.Open(context.Background(), "123")
}
type MyRestService struct {
*services.RestService
}
func NewMyRestService() *MyRestService {
c := &MyRestService{}
c.RestService = services.InheritRestService(c)
c.BaseRoute = "/my_service"
return c
}
// GET
func (c *MyRestService) myPageGet(res http.ResponseWriter, req *http.Request) {
params := req.URL.Query()
routeVars := mux.Vars(req)
result := params.Get("message") + ", " + routeVars["name"]
c.SendResult(res, req, result, nil)
}
// HEAD
func (c *MyRestService) myPageHead(res http.ResponseWriter, req *http.Request) {
c.SendResult(res, req, nil, nil)
}
// POST
func (c *MyRestService) myPagePost(res http.ResponseWriter, req *http.Request) {
correlationId := c.GetCorrelationId(req)
params := req.URL.Query()
routeVars := mux.Vars(req)
result := params.Get("message") + ", " + routeVars["name"]
var data string
bodyBytes, bodyErr := ioutil.ReadAll(req.Body)
_ = req.Body.Close()
if bodyErr != nil {
err := cerr.NewInternalError(correlationId, "JSON_CNV_ERR", "Cant convert from JSON to Data").WithCause(bodyErr)
c.SendError(res, req, err)
return
}
data = string(bodyBytes)
result = result + ", data:" + data
c.SendResult(res, req, result, nil)
}
// PUT
func (c *MyRestService) myPagePut(res http.ResponseWriter, req *http.Request) {
correlationId := c.GetCorrelationId(req)
params := req.URL.Query()
routeVars := mux.Vars(req)
result := params.Get("message") + ", " + routeVars["name"]
var data string
bodyBytes, bodyErr := ioutil.ReadAll(req.Body)
_ = req.Body.Close()
if bodyErr != nil {
err := cerr.NewInternalError(correlationId, "JSON_CNV_ERR", "Cant convert from JSON to Data").WithCause(bodyErr)
c.SendError(res, req, err)
return
}
data = string(bodyBytes)
result = result + ", data:" + data
c.SendResult(res, req, result, nil)
}
// Route registration
func (c *MyRestService) Register() {
c.RegisterRoute(
http.MethodGet, "/my_page/{name}",
nil,
c.myPageGet,
)
c.RegisterRoute(
http.MethodHead, "/my_page/{name}",
nil,
c.myPageHead,
)
c.RegisterRoute(
http.MethodPost, "/my_page/{name}",
nil,
c.myPagePost,
)
c.RegisterRoute(
http.MethodPut, "/my_page/{name}",
nil,
c.myPagePut,
)
}
import 'package:pip_services3_commons/pip_services3_commons.dart';
import 'package:pip_services3_rpc/pip_services3_rpc.dart';
class MyRestService extends RestService {
MyRestService() {
baseRoute = '/my_service';
}
// GET
FutureOr<Response> _myPageGet(Request req) async {
var result =
req.url.queryParameters['message']! + ', ' + req.params['name']!;
return await sendResult(req, result);
}
// HEAD
FutureOr<Response> _myPageHead(Request req) async {
return await sendResult(req, null);
}
// POST
FutureOr<Response> _myPagePost(Request req) async {
var data = json.decode(await req.readAsString());
var result = req.url.queryParameters['message']! +
', ' +
req.params['name']! +
', ' +
'data:' +
data['data1'];
return await sendResult(req, result);
}
// PUT
FutureOr<Response> _myPagePut(Request req) async {
var data = json.decode(await req.readAsString());
var result = req.url.queryParameters['message']! +
', ' +
req.params['name']! +
', ' +
'data:' +
data['data1'];
return await sendResult(req, result);
}
// Route registration
@override
void register() {
registerRoute('get', '/my_page/<name>', null, _myPageGet);
registerRoute('head', '/my_page/<name>', null, _myPageHead);
registerRoute('post', '/my_page/<name>', null, _myPagePost);
registerRoute('put', '/my_page/<name>', null, _myPagePut);
}
}
// Instantiation
var myRestService = MyRestService();
// REST service configuration
myRestService.configure(ConfigParams.fromTuples([
'connection.protocol',
'http',
'connection.host',
'localhost',
'connection.port',
15235
]));
// Connection
await myRestService.open('123');
# Pre-requisites
from bottle import request
from pip_services3_rpc.services import RestService
from pip_services3_commons.config import ConfigParams
class MyRestService(RestService):
def __init__(self):
super(MyRestService, self).__init__()
self._base_route = "/my_service"
# GET
def my_page_get(self, name):
result = f"{request.query.get('message')}, {name}"
return self.send_result(result)
# HEAD
def my_page_head(self, name):
return self.send_result(None)
# POST
def my_page_post(self, name):
body_data = self._get_data()
result = f"{request.query.get('message')}, {name}, " \
f'data:{body_data.get("data1")}'
return self.send_result(result)
# PUT
def my_page_put(self, name):
body_data = self._get_data()
result = f"{request.query.get('message')}, {name}, " \
f'data:{body_data.get("data1")}'
return self.send_result(result)
# Route registration
def register(self):
self.register_route(method="GET", route="/my_page/<name>", schema=None, handler=self.my_page_get)
self.register_route(method="HEAD", route="/my_page/<name>", schema=None, handler=self.my_page_head)
self.register_route(method="POST", route="/my_page/<name>", schema=None, handler=self.my_page_post)
self.register_route(method="PUT", route="/my_page/<name>", schema=None, handler=self.my_page_put)
# Instantiation
service = MyRestService()
# Configuration
service.configure(ConfigParams.from_tuples("connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15231))
# Connection
service.open("123")
The REST client
Now that we have our REST service, we build a REST client that connects to it. This client has a function for each of the HTTP methods which calls the corresponding methods in our REST service.
Once we have defined our component, we instantiate and configure it, pointing toward the endpoint previously defined in the REST service. Then, we connect it to the service with the open() method. The code below shows how to do this:
import { ConfigParams } from "pip-services3-commons-nodex";
import { RestClient } from "pip-services3-rpc-nodex";
export class MyRestClient extends RestClient {
public constructor() {
super();
this._baseRoute = '/my_service';
}
// GET
public async getDataGet(correlationId: string, name: string): Promise<string> {
let result = await this.call<string>("get", "/my_page/" + name, correlationId, { message: 'Hello' });
return result;
}
// HEAD
public async getDataHead(correlationId: string, name: string): Promise<string> {
let result = await this.call<string>("head", "/my_page/" + name, correlationId, { message: 'Hello' });
return result;
}
// POST
public async getDataPost(correlationId: string, name: string): Promise<string> {
let result = await this.call<string>("post", "/my_page/" + name, correlationId, { message: 'Hello' }, { data1: 'my data' });
return result;
}
// PUT
public async getDataPut(correlationId: string, name: string): Promise<string> {
let result = await this.call<string>("put", "/my_page/" + name, correlationId, { message: 'Hello' }, { data1: 'my data' });
return result;
}
}
// Instantiation
let client = new MyRestClient();
// REST client configuration
client.configure(ConfigParams.fromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15235
));
// Connection
client.open("123")
using PipServices3.Commons.Config;
using PipServices3.Rpc.Clients;
class MyRestClient: RestClient
{
public MyRestClient()
{
_baseRoute = "/my_service";
}
public async Task<string> GetDataGet(string correlationId, string name)
{
return await this.CallAsync<string>(correlationId, HttpMethod.Get, "/my_page/" + name + "?message=Hello");
}
public async Task<string> GetDataHead(string correlationId, string name)
{
return await this.CallAsync<string>(correlationId, HttpMethod.Head, "/my_page/" + name + "?message=Hello");
}
public async Task<string> GetDataPost(string correlationId, string name)
{
return await this.CallAsync<string>(correlationId, HttpMethod.Post, "/my_page/" + name + "?message=Hello", new { data1= "my data" });
}
public async Task<string> GetDataPut(string correlationId, string name)
{
return await this.CallAsync<string>(correlationId, HttpMethod.Put, "/my_page/" + name + "?message=Hello", new { data1 = "my data" });
}
}
// Instantiation
var client = new MyRestClient();
// REST client configuration
client.Configure(ConfigParams.FromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15235
));
// Connection
await client.OpenAsync("123");
import (
"context"
"net/http"
cconf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
cdata "github.com/pip-services3-gox/pip-services3-commons-gox/data"
"github.com/pip-services3-gox/pip-services3-rpc-gox/clients"
)
func main() {
// Instantiation
client := NewMyRestClient()
// REST client configuration
client.Configure(context.Background(), cconf.NewConfigParamsFromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15235,
))
// Connection
client.Open(context.Background(), "123")
}
type MyRestClient struct {
*clients.RestClient
}
func NewMyRestClient() *MyRestClient {
drc := MyRestClient{}
drc.RestClient = clients.NewRestClient()
drc.BaseRoute = "/my_service"
return &drc
}
// GET
func (c *MyRestClient) GetDataGet(ctx context.Context, correlationId string, name string) (result string, err error) {
params := cdata.NewEmptyStringValueMap()
params.Put("message", "hello")
response, err := c.Call(ctx, http.MethodGet, "/my_page/"+name, correlationId, params, nil)
if err != nil {
return "", err
}
return clients.HandleHttpResponse[string](response, correlationId)
}
// HEAD
func (c *MyRestClient) GetDataHead(ctx context.Context, correlationId string, name string) (result string, err error) {
params := cdata.NewEmptyStringValueMap()
params.Put("message", "hello")
response, err := c.Call(ctx, http.MethodHead, "/my_page/"+name, correlationId, params, nil)
if err != nil || response == nil {
return "", err
}
return clients.HandleHttpResponse[string](response, correlationId)
}
// POST
func (c *MyRestClient) GetDataPost(ctx context.Context, correlationId string, name string) (result string, err error) {
params := cdata.NewEmptyStringValueMap()
params.Put("message", "hello")
response, err := c.Call(ctx, http.MethodPost, "/my_page/"+name, correlationId, params, map[string]string{"data1": "my data"})
if err != nil {
return "", err
}
return clients.HandleHttpResponse[string](response, correlationId)
}
// PUT
func (c *MyRestClient) GetDataPut(ctx context.Context, correlationId string, name string) (result string, err error) {
params := cdata.NewEmptyStringValueMap()
params.Put("message", "hello")
response, err := c.Call(ctx, http.MethodPost, "/my_page/"+name, correlationId, params, map[string]string{"data1": "my data"})
if err != nil {
return "", err
}
return clients.HandleHttpResponse[string](response, correlationId)
}
import 'package:pip_services3_commons/pip_services3_commons.dart';
import 'package:pip_services3_rpc/pip_services3_rpc.dart';
class MyRestClient extends RestClient {
MyRestClient() {
baseRoute = '/my_service';
}
// GET
Future<String> getDataGet(String? correlationId, String name) async {
return await call(
'get', '/my_page/' + name, correlationId, {'message': 'Hello'}, null);
}
// HEAD
Future<String> getDataHead(String? correlationId, String name) async {
var res = await call(
'head', '/my_page/' + name, correlationId, {'message': 'Hello'}, null);
return res ?? '';
}
// POST
Future<String> getDataPost(String? correlationId, String name) async {
return await call('post', '/my_page/' + name, correlationId,
{'message': 'Hello'}, {'data1': 'my data'});
}
// PUT
Future<String> getDataPut(String? correlationId, String name) async {
return await call('put', '/my_page/' + name, correlationId,
{'message': 'Hello'}, {'data1': 'my data'});
}
}
// Instantiation
var client = MyRestClient();
// REST client configuration
client.configure(ConfigParams.fromTuples([
'connection.protocol',
'http',
'connection.host',
'localhost',
'connection.port',
15235
]));
// Connection
await client.open('123');
# Pre-requisites
from pip_services3_rpc.clients import RestClient
class MyRestClient(RestClient):
def __init__(self):
super().__init__()
self._base_route = '/my_service'
def get_data_get(self, correlation_id, name: str):
result = self._call("get", "/my_page/" + name, correlation_id, params={'message': 'Hello'})
return result
def get_data_head(self, correlation_id, name: str):
result = self._call("head", "/my_page/" + name, correlation_id, params={'message': 'Hello'}, data={
"data1": "my data"})
return result
def get_data_post(self, correlation_id, name: str):
result = self._call("post", "/my_page/" + name, correlation_id, params={'message': 'Hello'}, data={
"data1": "my data"})
return result
def get_data_put(self, correlation_id, name: str):
result = self._call("put", "/my_page/" + name, correlation_id, params={'message': 'Hello'}, data={
"data1": "my data"})
return result
# Instantiation
client = MyRestClient()
# Configuration
client.configure(ConfigParams.from_tuples("connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15231))
# Connection
client.open("123")
Using the different HTTP methods
Our last step is to call each of the client’s functions and obtain the respective results. The following commands and their outcomes show how to do this:
// GET
await client.getDataGet("123", "David");
// GET
await client.GetDataGet("123", "David");
// GET
res, err := client.GetDataGet(context.Background(), "123", "David")
// GET
await client.getDataGet("123", "David");
# GET
client.get_data_get("123", "David")
// HEAD
await client.getDataHead("123", "David");
// HEAD
await client.GetDataHead("123", "David");
// HEAD
res, err = client.GetDataHead(context.Background(), "123", "David")
// HEAD
await client.getDataHead("123", "David");
# HEAD
client.get_data_head("123", "David")
Note: the HEAD method produces no output.
// POST
await client.getDataPost("123", "David");
// POST
await client.GetDataPost("123", "David");
// POST
res, err = client.GetDataPost(context.Background(), "123", "David")
// POST
await client.getDataPost("123", "David");
# POST
client.get_data_post("123", "David")
// PUT
await client.getDataPut("123", "David");
// PUT
await client.GetDataPut("123", "David");
// PUT
res, err = client.GetDataPut(context.Background(), "123", "David")
// PUT
await client.getDataPut("123", "David");
# PUT
client.get_data_put("123", "David")
Final code
The code below summarizes the steps learned in the previous sections.
import { ConfigParams } from "pip-services3-commons-nodex";
import { RestClient, RestService } from "pip-services3-rpc-nodex";
export async function main() {
// Instantiation
let myRestService = new MyRestService();
// REST service configuration
myRestService.configure(ConfigParams.fromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15235
));
// Connection
await myRestService.open("123");
// Instantiation
let client = new MyRestClient();
// REST client configuration
client.configure(ConfigParams.fromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15235
));
// Connection
await client.open("123");
// Using the different HTTP methods
// GET
console.log("GET: " + await client.getDataGet("123", "David"));
// HEAD
console.log("HEAD: " + await client.getDataHead("123", "David"));
// POST
console.log("POST: " + await client.getDataPost("123", "David"));
// PUT
console.log("PUT: " + await client.getDataPut("123", "David"));
// Close REST service and REST client
await client.close("123");
await myRestService.close("123");
}
export class MyRestClient extends RestClient {
public constructor() {
super();
this._baseRoute = '/my_service';
}
// GET
public async getDataGet(correlationId: string, name: string): Promise<string> {
let result = await this.call<string>("get", "/my_page/" + name, correlationId, { message: 'Hello' });
return result;
}
// HEAD
public async getDataHead(correlationId: string, name: string): Promise<string> {
let result = await this.call<string>("head", "/my_page/" + name, correlationId, { message: 'Hello' });
return result;
}
// POST
public async getDataPost(correlationId: string, name: string): Promise<string> {
let result = await this.call<string>("post", "/my_page/" + name, correlationId, { message: 'Hello' }, { data1: 'my data' });
return result;
}
// PUT
public async getDataPut(correlationId: string, name: string): Promise<string> {
let result = await this.call<string>("put", "/my_page/" + name, correlationId, { message: 'Hello' }, { data1: 'my data' });
return result;
}
}
export class MyRestService extends RestService {
public constructor() {
super();
this._baseRoute = "/my_service";
}
// GET
public async myPageGet(req: any, res: any): Promise<void> {
let result = req.query.message + ", " + req.route.params.name;
this.sendResult(req, res, result);
}
// HEAD
public async myPageHead(req: any, res: any): Promise<void> {
this.sendResult(req, res, null);
}
// POST
public async myPagePost(req: any, res: any): Promise<void> {
let result = req.query.message + ", " + req.route.params.name + ", " + "data:" + req.body.data1;
this.sendResult(req, res, result);
}
// PUT
public async myPagePut(req: any, res: any): Promise<void> {
let result = req.query.message + ", " + req.route.params.name + ", " + "data:" + req.body.data1;
this.sendResult(req, res, result);
}
// Route registration
public register(): void {
this.registerRoute("GET", "/my_page/:name", null, this.myPageGet)
this.registerRoute("HEAD", "/my_page/:name", null, this.myPageHead)
this.registerRoute("POST", "/my_page/:name", null, this.myPagePost)
this.registerRoute("PUT", "/my_page/:name", null, this.myPagePut)
}
}
using System;
using System.IO;
using System.Net.Http;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using PipServices3.Commons.Convert;
using PipServices3.Commons.Config;
using PipServices3.Rpc.Services;
using PipServices3.Rpc.Clients;
namespace ExampleApp
{
class Program
{
static void Main(string[] args)
{
// Instantiation
var myRestService = new MyRestService();
// REST service configuration
myRestService.Configure(ConfigParams.FromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15235
));
// Connection
myRestService.OpenAsync("123").Wait();
// Instantiation
var client = new MyRestClient();
// REST client configuration
client.Configure(ConfigParams.FromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15235
));
// Connection
client.OpenAsync("123").Wait();
// Using the different HTTP methods
// GET
Console.WriteLine("GET: " + client.GetDataGet("123", "David").Result);
// HEAD
Console.WriteLine("HEAD: " + client.GetDataHead("123", "David").Result);
// POST
Console.WriteLine("POST: " + client.GetDataPost("123", "David").Result);
// PUT
Console.WriteLine("PUT: " + client.GetDataPut("123", "David").Result);
// Close REST service and REST client
client.CloseAsync("123").Wait();
myRestService.CloseAsync("123").Wait();
}
}
class MyRestClient: RestClient
{
public MyRestClient()
{
_baseRoute = "/my_service";
}
public async Task<string> GetDataGet(string correlationId, string name)
{
return await this.CallAsync<string>(correlationId, HttpMethod.Get, "/my_page/" + name + "?message=Hello");
}
public async Task<string> GetDataHead(string correlationId, string name)
{
return await this.CallAsync<string>(correlationId, HttpMethod.Head, "/my_page/" + name + "?message=Hello");
}
public async Task<string> GetDataPost(string correlationId, string name)
{
return await this.CallAsync<string>(correlationId, HttpMethod.Post, "/my_page/" + name + "?message=Hello", new { data1= "my data" });
}
public async Task<string> GetDataPut(string correlationId, string name)
{
return await this.CallAsync<string>(correlationId, HttpMethod.Put, "/my_page/" + name + "?message=Hello", new { data1 = "my data" });
}
}
// REST service
class MyRestService : RestService
{
public MyRestService(): base()
{
_baseRoute = "/my_service";
}
// GET
private async Task MyPageGet(HttpRequest request, HttpResponse response, RouteData routeData)
{
var name = routeData.Values["name"].ToString();
var message = request.Query.TryGetValue("message", out StringValues sortValues)
? sortValues.ToString()
: string.Empty;
var res = message + ", " + name;
await this.SendResultAsync(response, res);
}
// HEAD
private async Task MyPageHead(HttpRequest request, HttpResponse response, RouteData routeData)
{
await this.SendEmptyResultAsync(response);
}
// POST
private async Task MyPagePost(HttpRequest request, HttpResponse response, RouteData routeData)
{
var name = routeData.Values["name"].ToString();
var message = request.Query.TryGetValue("message", out StringValues sortValues)
? sortValues.ToString()
: string.Empty;
IDictionary<string, object> data = null;
using (var streamReader = new StreamReader(request.Body))
{
data = JsonConverter.ToMap(streamReader.ReadToEnd());
}
var res = message + ", " + name + ", " + "data:" + data["data1"];
await this.SendResultAsync(response, res);
}
// PUT
private async Task MyPagePut(HttpRequest request, HttpResponse response, RouteData routeData)
{
var name = routeData.Values["name"].ToString();
var message = request.Query.TryGetValue("message", out StringValues sortValues)
? sortValues.ToString()
: string.Empty;
IDictionary<string, object> data = null;
using (var streamReader = new StreamReader(request.Body))
{
data = JsonConverter.ToMap(streamReader.ReadToEnd());
}
var res = message + ", " + name + ", " + "data:" + data["data1"];
await this.SendResultAsync(response, res);
}
public override void Register()
{
this.RegisterRoute("get", "/my_page/{name}", MyPageGet);
this.RegisterRoute("head", "/my_page/{name}", MyPageHead);
this.RegisterRoute("post", "/my_page/{name}", MyPagePost);
this.RegisterRoute("put", "/my_page/{name}", MyPagePut);
}
}
}
import (
"context"
"fmt"
"io/ioutil"
"net/http"
"github.com/gorilla/mux"
cconf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
cdata "github.com/pip-services3-gox/pip-services3-commons-gox/data"
cerr "github.com/pip-services3-gox/pip-services3-commons-gox/errors"
"github.com/pip-services3-gox/pip-services3-rpc-gox/clients"
"github.com/pip-services3-gox/pip-services3-rpc-gox/services"
)
func main() {
// Instantiation
myRestService := NewMyRestService()
// REST service configuration
myRestService.Configure(context.Background(), cconf.NewConfigParamsFromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15235,
))
// Connection
myRestService.Open(context.Background(), "123")
////////////////////////////////////////////////////////////
// Instantiation
client := NewMyRestClient()
// REST client configuration
client.Configure(context.Background(), cconf.NewConfigParamsFromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15235,
))
// Connection
client.Open(context.Background(), "123")
// GET
res, err := client.GetDataGet(context.Background(), "123", "David")
fmt.Println(err)
fmt.Println(res)
// HEAD
res, err = client.GetDataHead(context.Background(), "123", "David")
fmt.Println(err)
fmt.Println(res)
// POST
res, err = client.GetDataPost(context.Background(), "123", "David")
fmt.Println(err)
fmt.Println(res)
// PUT
res, err = client.GetDataPut(context.Background(), "123", "David")
fmt.Println(err)
fmt.Println(res)
// Close REST service and REST client
_ = client.Close(context.Background(), "123")
_ = myRestService.Close(context.Background(), "123")
}
type MyRestClient struct {
*clients.RestClient
}
func NewMyRestClient() *MyRestClient {
drc := MyRestClient{}
drc.RestClient = clients.NewRestClient()
drc.BaseRoute = "/my_service"
return &drc
}
// GET
func (c *MyRestClient) GetDataGet(ctx context.Context, correlationId string, name string) (result string, err error) {
params := cdata.NewEmptyStringValueMap()
params.Put("message", "hello")
response, err := c.Call(ctx, http.MethodGet, "/my_page/"+name, correlationId, params, nil)
if err != nil {
return "", err
}
return clients.HandleHttpResponse[string](response, correlationId)
}
// HEAD
func (c *MyRestClient) GetDataHead(ctx context.Context, correlationId string, name string) (result string, err error) {
params := cdata.NewEmptyStringValueMap()
params.Put("message", "hello")
response, err := c.Call(ctx, http.MethodHead, "/my_page/"+name, correlationId, params, nil)
if err != nil || response == nil {
return "", err
}
return clients.HandleHttpResponse[string](response, correlationId)
}
// POST
func (c *MyRestClient) GetDataPost(ctx context.Context, correlationId string, name string) (result string, err error) {
params := cdata.NewEmptyStringValueMap()
params.Put("message", "hello")
response, err := c.Call(ctx, http.MethodPost, "/my_page/"+name, correlationId, params, map[string]string{"data1": "my data"})
if err != nil {
return "", err
}
return clients.HandleHttpResponse[string](response, correlationId)
}
// PUT
func (c *MyRestClient) GetDataPut(ctx context.Context, correlationId string, name string) (result string, err error) {
params := cdata.NewEmptyStringValueMap()
params.Put("message", "hello")
response, err := c.Call(ctx, http.MethodPost, "/my_page/"+name, correlationId, params, map[string]string{"data1": "my data"})
if err != nil {
return "", err
}
return clients.HandleHttpResponse[string](response, correlationId)
}
////////////////////////////////////////
type MyRestService struct {
*services.RestService
}
func NewMyRestService() *MyRestService {
c := &MyRestService{}
c.RestService = services.InheritRestService(c)
c.BaseRoute = "/my_service"
return c
}
// GET
func (c *MyRestService) myPageGet(res http.ResponseWriter, req *http.Request) {
params := req.URL.Query()
routeVars := mux.Vars(req)
result := params.Get("message") + ", " + routeVars["name"]
c.SendResult(res, req, result, nil)
}
// HEAD
func (c *MyRestService) myPageHead(res http.ResponseWriter, req *http.Request) {
c.SendResult(res, req, nil, nil)
}
// POST
func (c *MyRestService) myPagePost(res http.ResponseWriter, req *http.Request) {
correlationId := c.GetCorrelationId(req)
params := req.URL.Query()
routeVars := mux.Vars(req)
result := params.Get("message") + ", " + routeVars["name"]
var data string
bodyBytes, bodyErr := ioutil.ReadAll(req.Body)
_ = req.Body.Close()
if bodyErr != nil {
err := cerr.NewInternalError(correlationId, "JSON_CNV_ERR", "Cant convert from JSON to Data").WithCause(bodyErr)
c.SendError(res, req, err)
return
}
data = string(bodyBytes)
result = result + ", data:" + data
c.SendResult(res, req, result, nil)
}
// PUT
func (c *MyRestService) myPagePut(res http.ResponseWriter, req *http.Request) {
correlationId := c.GetCorrelationId(req)
params := req.URL.Query()
routeVars := mux.Vars(req)
result := params.Get("message") + ", " + routeVars["name"]
var data string
bodyBytes, bodyErr := ioutil.ReadAll(req.Body)
_ = req.Body.Close()
if bodyErr != nil {
err := cerr.NewInternalError(correlationId, "JSON_CNV_ERR", "Cant convert from JSON to Data").WithCause(bodyErr)
c.SendError(res, req, err)
return
}
data = string(bodyBytes)
result = result + ", data:" + data
c.SendResult(res, req, result, nil)
}
// Route registration
func (c *MyRestService) Register() {
c.RegisterRoute(
http.MethodGet, "/my_page/{name}",
nil,
c.myPageGet,
)
c.RegisterRoute(
http.MethodHead, "/my_page/{name}",
nil,
c.myPageHead,
)
c.RegisterRoute(
http.MethodPost, "/my_page/{name}",
nil,
c.myPagePost,
)
c.RegisterRoute(
http.MethodPut, "/my_page/{name}",
nil,
c.myPagePut,
)
}
import 'dart:async';
import 'dart:convert';
import 'package:pip_services3_commons/pip_services3_commons.dart';
import 'package:pip_services3_rpc/pip_services3_rpc.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf_router/shelf_router.dart';
void main(List<String> argument) async {
// Instantiation
var myRestService = MyRestService();
// REST service configuration
myRestService.configure(ConfigParams.fromTuples([
'connection.protocol',
'http',
'connection.host',
'localhost',
'connection.port',
15235
]));
// Connection
await myRestService.open('123');
// Instantiation
var client = MyRestClient();
// REST client configuration
client.configure(ConfigParams.fromTuples([
'connection.protocol',
'http',
'connection.host',
'localhost',
'connection.port',
15235
]));
// Connection
await client.open('123');
// Using the different HTTP methods
// GET
print('GET: ' + await client.getDataGet('123', 'David'));
// HEAD
print('HEAD: ' + await client.getDataHead('123', 'David'));
// POST
print('POST: ' + await client.getDataPost('123', 'David'));
// PUT
print('PUT: ' + await client.getDataPut('123', 'David'));
// Close REST service and REST client
await client.close('123');
await myRestService.close('123');
}
class MyRestClient extends RestClient {
MyRestClient() {
baseRoute = '/my_service';
}
// GET
Future<String> getDataGet(String? correlationId, String name) async {
return await call(
'get', '/my_page/' + name, correlationId, {'message': 'Hello'}, null);
}
// HEAD
Future<String> getDataHead(String? correlationId, String name) async {
var res = await call(
'head', '/my_page/' + name, correlationId, {'message': 'Hello'}, null);
return res ?? '';
}
// POST
Future<String> getDataPost(String? correlationId, String name) async {
return await call('post', '/my_page/' + name, correlationId,
{'message': 'Hello'}, {'data1': 'my data'});
}
// PUT
Future<String> getDataPut(String? correlationId, String name) async {
return await call('put', '/my_page/' + name, correlationId,
{'message': 'Hello'}, {'data1': 'my data'});
}
}
class MyRestService extends RestService {
MyRestService() {
baseRoute = '/my_service';
}
// GET
FutureOr<Response> _myPageGet(Request req) async {
var result =
req.url.queryParameters['message']! + ', ' + req.params['name']!;
return await sendResult(req, result);
}
// HEAD
FutureOr<Response> _myPageHead(Request req) async {
return await sendResult(req, null);
}
// POST
FutureOr<Response> _myPagePost(Request req) async {
var data = json.decode(await req.readAsString());
var result = req.url.queryParameters['message']! +
', ' +
req.params['name']! +
', ' +
'data:' +
data['data1'];
return await sendResult(req, result);
}
// PUT
FutureOr<Response> _myPagePut(Request req) async {
var data = json.decode(await req.readAsString());
var result = req.url.queryParameters['message']! +
', ' +
req.params['name']! +
', ' +
'data:' +
data['data1'];
return await sendResult(req, result);
}
// Route registration
@override
void register() {
registerRoute('get', '/my_page/<name>', null, _myPageGet);
registerRoute('head', '/my_page/<name>', null, _myPageHead);
registerRoute('post', '/my_page/<name>', null, _myPagePost);
registerRoute('put', '/my_page/<name>', null, _myPagePut);
}
}
# REST service
# Pre-requisites
from bottle import request
from pip_services3_rpc.services import RestService
from pip_services3_commons.config import ConfigParams
class MyRestService(RestService):
def __init__(self):
super(MyRestService, self).__init__()
self._base_route = "/my_service"
# GET
def my_page_get(self, name):
result = f"{request.query.get('message')}, {name}"
return self.send_result(result)
# HEAD
def my_page_head(self, name):
return self.send_result(None)
# POST
def my_page_post(self, name):
body_data = self._get_data()
result = f"{request.query.get('message')}, {name}, " \
f'data:{body_data.get("data1")}'
return self.send_result(result)
# PUT
def my_page_put(self, name):
body_data = self._get_data()
result = f"{request.query.get('message')}, {name}, " \
f'data:{body_data.get("data1")}'
return self.send_result(result)
# Route registration
def register(self):
self.register_route(method="GET", route="/my_page/<name>", schema=None, handler=self.my_page_get)
self.register_route(method="HEAD", route="/my_page/<name>", schema=None, handler=self.my_page_head)
self.register_route(method="POST", route="/my_page/<name>", schema=None, handler=self.my_page_post)
self.register_route(method="PUT", route="/my_page/<name>", schema=None, handler=self.my_page_put)
# Instantiation
service = MyRestService()
# Configuration
service.configure(ConfigParams.from_tuples("connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15231))
# Connection
service.open("123")
# REST client
# Pre-requisites
from pip_services3_rpc.clients import RestClient
class MyRestClient(RestClient):
def __init__(self):
super().__init__()
self._base_route = '/my_service'
def get_data_get(self, correlation_id, name: str):
result = self._call("get", "/my_page/" + name, correlation_id, params={'message': 'Hello'})
return result
def get_data_head(self, correlation_id, name: str):
result = self._call("head", "/my_page/" + name, correlation_id, params={'message': 'Hello'}, data={
"data1": "my data"})
return result
def get_data_post(self, correlation_id, name: str):
result = self._call("post", "/my_page/" + name, correlation_id, params={'message': 'Hello'}, data={
"data1": "my data"})
return result
def get_data_put(self, correlation_id, name: str):
result = self._call("put", "/my_page/" + name, correlation_id, params={'message': 'Hello'}, data={
"data1": "my data"})
return result
# Instantiation
client = MyRestClient()
# Configuration
client.configure(ConfigParams.from_tuples("connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 15231))
# Connection
client.open("123")
# Using the different HTTP methods
# GET
print("GET: ", client.get_data_get("123", "David"))
# HEAD
print("HEAD: ", client.get_data_head("123", "David"))
# POST
print("POST: ", client.get_data_post("123", "David"))
# PUT
print("PUT: ", client.get_data_put("123", "David"))
# Close REST service and REST client
client.close("123")
service.close("123")
Which after running produces the following outcome:
Wrapping up
In this tutorial, we have learned how to create a REST client that communicates via an endpoint defined by a REST service. We used the RestClient and the RestService classes to define these components, and we added functions for the GET, HEAD, POST and PUT methods in the service and the client. We concluded by creating a program that summarizes all the learned concepts.