goplus / yap

Yet Another Go/Go+ HTTP Web Framework
Apache License 2.0
19 stars 9 forks source link

Proposal for enhanced routing mechanism to support multi-method and wildcard-method syntax #105

Open aofei opened 5 months ago

aofei commented 5 months ago

Introduction

The current routing mechanism in Yap, exemplified by file names like get_p_#id.yap, effectively maps a single HTTP method to a specific route, e.g., GET /p/:id. However, this approach presents limitations when one wishes to register multiple HTTP methods for the same route or utilize a wildcard to match any method for a given route. This proposal aims to extend the current routing syntax to accommodate these use cases.

Proposed enhancements

  1. Support for multiple methods: To allow multiple methods to be associated with a single route, I propose a syntax where methods are concatenated using a , sign. For instance, get,head_p_#id.yap would register the /p/:id route for both GET and HEAD methods.
  2. Wildcard method support: To enable a route to respond to any HTTP method, I propose the use of an * prefix. For example, *_p_#id.yap would match the /p/:id route for any HTTP method. This would replace the existing but less intuitive handle_p_#id.yap, aligning with the more recognized wildcard symbol *. (HANDLE is not a standard HTTP method, but non-standard methods are allowed in the HTTP spec, e.g., WebDAV uses many non-standard methods.)

Conflict resolution

In cases where multiple files might match a request (e.g., *_p_#id.yap and get_p_#id.yap), the router should prioritize the more specific match. Therefore, a GET /p/:id request would be handled by get_p_#id.yap over *_p_#id.yap, given the explicit mention of the GET method in the former.

Rationale

Conclusion

I believe these enhancements will make Yap more powerful and flexible, catering to a broader range of routing requirements.

aofei commented 5 months ago

For the support of multi-method syntax, there's a workaround worth mentioning. One can avoid duplicating the same .yap files for different methods by utilizing symbolic links.

For example:

$ gop mod init hello
$ gop get github.com/goplus/yap@latest
$ echo 'html `<html><body>Hello, YAP!</body></html>`' > get.yap
$ ln -s get.yap head.yap
$ gop mod tidy
$ gop run .
$ curl -i localhost:8080
HTTP/1.1 200 OK
Content-Length: 37
Content-Type: text/html
Date: Mon, 11 Mar 2024 07:53:23 GMT

<html><body>Hello, YAP!</body></html>
$ curl -I localhost:8080
HTTP/1.1 200 OK
Content-Length: 37
Content-Type: text/html
Date: Mon, 11 Mar 2024 07:53:26 GMT
xushiwei commented 5 months ago

https://github.com/goplus/yap/pull/108 - default http HEAD implementation.