DEV Community

Cover image for Rack Middleware for the Web Monetization API
Ben Greenberg
Ben Greenberg

Posted on

Rack Middleware for the Web Monetization API

Initially, I did not know if there was a relevant way for me to participate in this DEV hackathon since the Web Monetization API is primarily a client-side topic, and as a backend dev, it wasn't apparent where my point of contribution would be.

However, I then read this idea from fellow DEV community member Kinyanjui Wangonya to create a Python binding for the Web Monetization API and I had a moment of inspiration!

It was time to build middleware for the Ruby ecosystem to handle the different states returned from the API.

What I built

I built Rack middleware, rack-monetize, that can be used in either a standalone Ruby application or mounted into a Rails application.

The middleware functions like other middleware in that it sits in the middle of the stack and watches the request parameters coming into the application.

When the middleware finds parameters related to the Web Monetization API it intercepts it and processes it. If the data value of the parameter matches one of the states documented in the API then it lets the data continue on down the stack of the app. If, however, the data is not one of the expected states then it stops the flow of the app and returns a 403 HTTP status.

This functionality can be built by every Ruby developer for each application they are integrating the web monetization API, but the middleware abstracts that process for them, and makes it as simple as including use Rack::Monetize::ProcessMonetizeState in their config.ru or config.middleware.use Rack::Monetize::ProcessMonetizeState in their config/application.rb file if it is inside Rails.

The gem is available on RubyGems and the code is available on GitHub:

GitHub logo bencgreenberg / rack-monetize

Rack Web Monetization Middleware

Submission Category:

Foundational Technology

Demo

The app (v0.1.0) can be found on RubyGems.

The client application would need to send the Web Monetization API state to a backend with rack-monetize installed. The state needs to be sent with the monetization_state key.

Link to Code

GitHub logo bencgreenberg / rack-monetize

Rack Web Monetization Middleware

How I built it

I built it by first using the new gem functionality in bundler:

$ bundle gem rack-monetize
Enter fullscreen mode Exit fullscreen mode

This initiates a series of question prompts, which I answered. These questions are about the license, code of conduct, etc.

Once that was done, I filled in the details of the rack-monetize.gemspec, which is used to build out the gem and I added rack as a runtime dependency:

spec.add_runtime_dependency('rack', '~> 2.2', '>= 2.2.2')
Enter fullscreen mode Exit fullscreen mode

At that point, I was ready to write the code itself, which lives inside /lib/rack/monetize/process_monetize_state.rb.

The ProcessMonetizeState#initialize method takes in the app as an argument and assigns it to an instance variable, @app, to use it in the rest of the code.

The #call method will return the environment back to the stack if the params do not include monetization_state.

If the params do include monetization_state it invokes the #check_monetization_state method.

The method returns true if the state is one of: stopped, pending, started or undefined. (According to the API Documentation undefined will be present until web monetization is built into the browsers.)

The middleware will return a 403 HTTP status if there is a monetization_state parameter, but its value is not one of the aforementioned states.

Top comments (5)

Collapse
 
wangonya profile image
Kelvin Wangonya

Very cool! I'm glad my idea inspired you.

Collapse
 
bengreenberg profile image
Ben Greenberg

Thank you for the inspiration!

Collapse
 
rhymes profile image
rhymes

Wow, great idea Ben!

Collapse
 
bengreenberg profile image
Ben Greenberg

Thanks, but the inspiration comes from Kinyanjui's post I mentioned above! All I did was implement his idea in Ruby :)

Collapse
 
ben profile image
Ben Halpern

This is really neat!