Scala @ PayPal: Cascade

I recently wrote about a Scala Style Guide that my team and I at PayPal recently released.

I’m following up here about Cascade, an Scala project that I open sourced a while ago (this post has been a long time coming!)

 History

Cascade started way back I was at StackMob as a bunch of utilities thrown together ad-hoc. It grew over time into a big disorganized repository called “stackmob-common.”

When I joined PayPal, my team and I started bringing it over to an internal repository one piece at a time. We wanted to make sure its new home was clean, simple and organized.

 Goals

Fast forward to today. We’ve (obviously) open sourced it and divided it into 4 major pieces.

I also created a set of goals that everything has to follow. I want Cascade to stay simple and focused, because that’s how it’s stayed useful for us.

Each piece must:

  1. Work well with Scala and the Typesafe libraries.
  2. Work independently from each other.
  3. Be well defined in their functionality.
  4. Minimize the number of external dependencies.
  5. Related to (4) - use the features of the Scala standard library before building their own.

 HTTP Support

Both at PayPal and StackMob, we wrote a lot of REST servers. Previous incarnations of the library grew organically with primarily JSON & HTTP in mind, so naturally Cascade is also focused primarily around HTTP and JSON.

Over time, we’ve built utilities for:

Notice the Scalamachine bullet in the list - that was an entire HTTP server library based on the Webmachine HTTP state machine.

When we switched to Spray at StackMob, we built a rough re-implementation of the state machine, and when we came to PayPal, we ported it over and simplified it a lot. We trimmed it down to expose only the states that we use the most in practice.

We don’t have any Scalamachine, Netty or Finagle utilities in Cascade.

The library ships only with the simplified implementation of the HTTP state machine and we call it the resource model.

Finagle and Netty are good choices in some cases, so if you’re considering using Cascade, check out the example code to see if the resource model is right for you.

 The Resource Model

Building services in this model lets us reason about collections of Spray routes instead of one at a time. A single resource can be responsible for one or more routes, and we get some useful and powerful guarantees from Cascade’s implementation:

For example, one of the states in all resources is authentication and authorization (“auth”). In the auth state, you can execute your logic and send an appropriate message back to sender. If auth succeeded, Cascade will send a message back to transition to the next state (processing the actual request). Otherwise it will shut down your state actor and return a 401 Unauthorized to the client.

Today at PayPal, we have resource-based services in production. It achieves my original goals for Cascade’s success (listed above), and it’s also very easy to read, understand and teach. All great things to have when 20+ people are sharing a codebase.

 The Future

Cascade is useful and powerful for my team and I because it’s small. Almost all the other benefits are derived from that one:

Right now, Cascade is so core to what we do that my team and I take it for granted. When we find something we want to add, we just go through the process to add it and it’s that simple.

We’ll continue to grow Cascade carefully according to the goals, and I want to share it with the community now too.

File an issue, submit a PR, or tweet/email me if you have ideas/feedback, and definitely let me know if you’re using it.

I’m looking forward to hearing what you think!

 
32
Kudos
 
32
Kudos

Now read this

Type Safety For Python Functions

Have you ever written something like this Python code? def myFunction(a, b): if type(a) != str and type(b) != int: raise "a must be a string or b must be an int" #do some more stuff I find myself writing that all the time. I want the... Continue →