xmidt-org / wrp-go

go implementation of the Web Routing Protocol
Apache License 2.0
4 stars 7 forks source link

Client type #64

Closed johnabass closed 2 years ago

johnabass commented 2 years ago

We really need a wrp-specific client, not unlike consul or similar libraries.

An outline of the simplest, initial version of this would be:

package wrpclient

// Interface is the client interface that application code would be written to
type Interface interface {
    Do(ctx context.Context, response, request interface{}) error
}

type HTTPClient interface {
    Do(*http.Request) (*http.Response, error)
}

// Client implements Interface, and thus can be decorated to arbitrary depth.
type Client struct {
    // initial fields, this is by no means complete ....

    // URL is the full location for the serverside wrp endpoint.
    // If unset, use talaria's URI at localhost, which the port used in talaria's docker image
    URL string

    // RequestFormat would be the wrp Format to use for all requests, which specifies the wrp.Encoder.
    // If unset, defaults to JSON, which is what the wrp package defaults to.
    RequestFormat wrp.Format

    // If unset, defaults to net/http.DefaultClient
    HTTPClient HTTPClient
}

func (c *Client) Do(ctx context.Context, response, request interface{}) error {
    // The basic workflow here is:
    // (1) create an *http.Request, using c.RequestFormat to marshal the body and the client URL
    // (2) use c.HTTPClient or http.DefaultClient to execute the HTTP transaction
    // (3) translate the response using the wrp package and the response as the target of unmarshaling
}

Defining the wrpclient.Interface in that manner gives clients flexibility. A few examples of client usage:

package main

func Example1(c wrpclient.Interface) error {
    var in, out wrp.Message
    // fill out "in" ...

    return c.Do(context.Background(), &out, in)
}

func Example2(ctx context.Context, c wrpclient.Interface) error {
    var out wrp.Message
    in := wrp.CRUD{
        // ...
    }

    return c.Do(ctx, &out, in)
}

func Example3(ctx context.Context, c wrpclient.Interface) error {
    var out wrp.Message
    in := map[string]interface{}{
        // ...
    }

     return c.Do(ctx, &out, in)
}

This is just a rough draft. It will change as we refactor it and use it closer to production.