Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[commandbus] Add formal mechanism for validating commands #71

Closed
maxekman opened this issue Jan 12, 2017 · 5 comments
Closed

[commandbus] Add formal mechanism for validating commands #71

maxekman opened this issue Jan 12, 2017 · 5 comments

Comments

@maxekman
Copy link
Member

For example a validation method on the aggregate interface, or a middleware that runs before handling the command in the aggregate.

@maxekman
Copy link
Member Author

maxekman commented Sep 17, 2017

A flexible way to do it would be to create a separate CommandHandler middleware that does only validation.

@maxekman maxekman changed the title Add formal mechanism for validating commands [commandbus] Add formal mechanism for validating commands Mar 21, 2018
@apterf
Copy link
Contributor

apterf commented Jul 27, 2018

Hi Max,

It will be great to have this implemented and hope to help with it.

As you suggested, I'm planning to add a middleware validator
as middleware/commandhandler/validator/commandhandler.go.

  1. Add a command interface with method Validate()
type Command interface {
	eh.Command

	// Validate returns the error when validating the command.
	Validate() error
}
  1. The middleware will simply call the validation, if failed, return with the error
func NewMiddleware() eh.CommandHandlerMiddleware {
	return eh.CommandHandlerMiddleware(func(h eh.CommandHandler) eh.CommandHandler {
		return eh.CommandHandlerFunc(func(ctx context.Context, cmd eh.Command) error {
			if c, ok := cmd.(Command); ok {
				err := c.Validate()
				if err != nil {
					return err
				}
			}

			// Immediate command execution.
			return h.HandleCommand(ctx, cmd)
		})
	})
}

How do you feel about that? Any other idea?

@apterf
Copy link
Contributor

apterf commented Jul 27, 2018

And also, we found a problem (maybe a separate issue) when a struct with private fields was used in a command.

https://github.com/looplab/eventhorizon/blob/master/command.go#L155-L167

According to existing logic, private fields will be skipped and the struct will also be treated as zero value.

https://github.com/looplab/eventhorizon/blob/master/commandhandler/aggregate/commandhandler.go#L57-L60

e.g. a custom type from time.Time

type customTime time.Time

If validator can be added to each different command, can we make it an optional check?
It will be quite difficult to make it generic and always suitable for all cases.

@maxekman
Copy link
Member Author

The approach for the validator looks good.

As for the other issue, If you want to open a new issue for that it would also be welcome.

@apterf
Copy link
Contributor

apterf commented Jul 30, 2018

Great I will go for this then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants