Background
I have a package that has a bunch of function calls to get/set data via API calls. I’m looking at implementing a middleware that will pick up jobs from a queue where each job will provide the name of the method and the respective method arguments for the package. The middleware is then responsible for calling the corresponding functions from the package.
The method is a JSON string and the arguments is a JSON array
of strings.
Here are some example function signatures for the app package:
type App struct {}
...
func(a *App) GetUser(username string){}
func(a *App) CreateGroup(groupname string){}
func(a *App) RemoveUserFromGroup(username, groupname string) (err){}
The middleware begins by getting messages from the queue and spins up a goroutine to process the message via Process()
function as shown below:
func (m *Middleware) Process(a *App, method string, args []interface{}) {
switch method {
case "GetUser", "CreateGroup":
m.Call(method, arg[0])
case "RemoveUserFromGroup":
username := arg[0]
groupname := arg[0]
m.Call(method, arg[0], arg[1])
// More case statements
...
The Call()
function uses the reflect
package invoke the methods with supplied arguments at run time and does the needful.
Question
As you may have noticed the the Process()
function will have many case
statements to satisfy:
- The right number of arguments are passed
- Given the arguments from the queue is a slice, there is a need to construct objects/types e.g structs as arguments for some methods.
A further constraint I have is I can’t change the app package functions. e.g: argument types etc.
Although a switch/case
statement works, they seem like an inelegant way to deal with the requirement. I was interested to know if there is a better pattern available to handle these sort of cases?