Skip to content

Should we migrate the web-app component to Lua? #304

@GUI

Description

@GUI

For background, API Umbrella's architecture can be separated into 3 main components:

  • gatekeeper: Custom proxy and routing. The main API gateway portion of the code. Written in Lua inside nginx/OpenResty
  • web-app: Admin APIs and admin login. Provides all the CRUD administrative APIs and handles admin logins via various authentication providers (e.g. Google oauth2, or LDAP). A Ruby on Rails application.
  • admin-ui: The admin user interface. An EmberJS client-side app that utilizes the various admin APIs provided by web-app.

Since we migrated the gatekeeper to Lua, it's sort of been in the back of my mind to consolidate the web-app APIs to be written in Lua too. This type of task is more in the realm of "cleanup" or "maybe nice to have," so I don't think this is particularly pressing (and perhaps doesn't even make sense at all), but I wanted to create a ticket to track this and list out some current pros/cons.

Pros:

  • Simplify the code base and reduce the polyglot nature of things a bit. If all of the APIs were in Lua, that would simplify the languages and architecture a bit, so that all the server-side code was written in Lua (with the admin interface still being JavaScript).
  • Reduce number of server components. We could forego running the Rails server (Puma), and the Rails background processing (delayed_job). Less moving parts is always nice.
  • Reduce server memory usage. Running the Rails app uses a fair amount of memory for a component that isn't heavily utilized. It would make our stack footprint a little lighter with these APIs living in Lua.
  • Speed. While speed hasn't really been an issue for the web APIs to date, Lua-based APIs would probably be faster. But these APIs aren't heavily hit with the exception maybe of the API key signup API that might see benefits under heavier load.

Cons:

  • Lack of OmniAuth: This is one of the bigger current pitfalls. We offer a variety of ways to login to the admin that hook into other authentication providers, like Google, GitHub, LDAP, CAS, etc. Being able to easily leverage OmniAuth and its multitude of login strategies is pretty nice and a significant efficiency gain.

    There's just not an equivalent mature and pluggable authentication system for Lua/OpenResty that I'm aware of. We could certainly implement the necessary authentication code (in a lot of cases, it's not actually that complex), but it's nice to not have have to deal with this. And just last month, I was needing to look at adding SAML integration for the admin login, and it's certainly easier to add an OmniAuth plugin to handle that versus rolling our own.

  • Mailer libraries: Another bigger current pitfall. We primarily send e-mail for the API key info. Using Rails, we have a pretty easy and configurable interface with ActionMailer. Using the same ActionMailer API, we can easily send mail via sendmail and SMTP. Or there's theoretically hooks to send via other means (eg, I've worked on the sendgrid-actionmailer library to send via an HTTPS API). All that's required to switch implementations is some configuration tweaks.

    Again, this hits upon a relative weakness in the current Lua/OpenResty ecosystem. There is a lua-resty-smtp library, but it seems to still be missing some important functionality, like STARTTLS support. And if we wanted to support sendmail, we'd presumably have to do something custom, probably utilizing lua-resty-shell.

  • Lack of ORM: We currently use Mongoid as an ORM for our data in Mongo. This provides some niceties around validation and organizing our models. There's not really an equivalent ORM for Mongo in Lua. That being said, our data models are pretty simple, and we have to fight to workaround Mongoid sometimes, so this doesn't seem like as big of a deal to me.

  • It's more work: Keeping things the same is obviously the quicker and easier solution. :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions