Skip to content

Latest commit

 

History

History
72 lines (41 loc) · 2.3 KB

developer.md

File metadata and controls

72 lines (41 loc) · 2.3 KB

Implementation decisions

This part cover some of the implementation decisions taken along the development process.

Decision #1: Only context

Handler functions has 1 parameter:

func (c *golax.Context) {
    
}

Why not w, r and c and maintain developer compatibility?

We would ended up with the following signature:

func (w http.ResponseWriter, r *http.Request, c *golax.Context) {
    
}

Old code is not going to work by doing copy&paste, but you only have to replace:

  • w by c.Response
  • r by c.Request

Making this decision is hard but c *golax.Context is much easier to remember and to write.

About code readability, w.Write(...) is shorter but c.Response.Write(...) is more semantic.

Decision #2: The Hollywood Principle

Changing Middleware vs Interceptor is a semantic decision to break up with Sinatra styled frameworks.

Typical middlewares should call to next() to continue chaining execution. On the other hand, an interceptor has two parts Before and After and you don't have to call any next() or similar. It follows the Hollywood Principle known as "Don't call us, we'll call you".

Decision #3: Interceptor flow

Normal flow

Each node in the routing hierarchy executes all its parent nodes interceptors. Why?

This is the desired behaviour for the 95% of the cases or even more. With several advantages:

  • You don't have to repeat the interceptor (or middleware) in every endpoint.
  • You get prettier, more readable and understandable code.
  • Avoid human errors.

Decision #4: Custom methods

Support for custom methods is a routing feature, you are free to use or not. It does not mean coupling with other libraries or adding non-routing responsibilites.

If you do not use custom methods (.Operation("your-custom-method")) the router behaves exactly as if it does not support them. In other words, it is backwards compatible.