I’m working on a REST client library, and recently started working on adding support for sending batch messages.
However, I don’t like the current design. It requires you to maintain large Client and RequestMessage classes with identical method signatures.
I am looking for a way to consolidate the two classes.
The original Client class’s methods contained all the code needed to prepare and send the request:
class Client(object):
def __init__(self, config):
self.request = Request(config, "application/json")
def create_vertex(self, data):
path = "vertices"
params = remove_null_values(data)
self.request.post(path, params)
To add support for batch messages, I pulled out the guts of the code inside the each Client method, and put it into a separate RequestMessage class so that you can add the messages to the batch without sending it, until you’re ready:
class Client(object):
def __init__(self, config):
self.request = Request(config, "application/json")
self.message = RequestMessage(config)
def create_vertex(self, data):
message = self.message.create_vertex(data)
return self.request.send(message)
# ...more REST client methods...
def batch(self, messages):
path = "batch"
params = messages
return self.request.post(path, params)
class RequestMessage(object):
def __init__(self, config):
self.config = config
def create_vertex(self, data):
path = "vertices"
params = remove_null_values(data)
return POST, path, params
# ...more REST client methods...
But I don’t like the design because now you have to maintain the Client and RequestMessage class — two large classes with identical signatures.
Here’s what the Batch class looks like:
class Batch(object):
def __init__(self, client):
self.client = client
self.messages = []
def add(self, message):
self.messages.append(message)
def send(self):
return self.client.batch(self.messages)
Here’s example usage for creating a vertex on the server:
>>> client = Client(config)
>>> vertex = client.create_vertex({'name':'James'})
Here’s example usage for creating a batch of vertices on the server:
>>> message1 = client.message.create_vertex({'name':'James'})
>>> message2 = client.message.create_vertex({'name':'Julie'})
>>> batch = Batch(client)
>>> batch.add(message1)
>>> batch.add(message2)
>>> batch.send()
Batch is used less frequently than Client so I want to make the normal Client interface easiest to use.
Here’s one idea, but I’m not quite sure how to achieve it or if something else would be better:
>>> vertex = client.create_vertex(data)
>>> message = client.create_vertex(data).message()
My personal preference is an API like:
That way you use the exact same function, you’re just giving it more data. Typical usage would probably look more like: