Open-source project
spoddutur/spark-as-service-using-embedded-server avatar
spoddutur/spark-as-service-using-embedded-server

spark-as-service puts an HTTP server inside the Spark application, not the other way round

This application comes as Spark2.1-as-Service-Provider using an embedded, Reactive-Streams-based, fully asynchronous HTTP server

50 stars21 forksScalaLicense varies

At a glance

What is it?
A small Scala demonstration of serving cluster computation over REST, built so that the web layer is a transport detail rather than the application. Four demo routes expose it, one config file and a set of Maven arguments hold the settings, and the last recorded push is from July 2023, which is the first thing to weigh.
Who is it for?
Read this as a shape rather than a dependency. The idea it demonstrates, that you build on top of your computation engine and bolt an HTTP layer on for transport only, is the part that transfers; the code itself is pinned to a Spark major version from several years ago and has not moved since July 2023.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Probably not. The repository last received commits 39 months ago, on July 16, 2023.
What is it written in?
Mainly Scala, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 4, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • spoddutur/spark-as-service-using-embedded-server50 ★ · +0
Star history
Repository2026-08-182026-10-04
spoddutur/spark-as-service-using-embedded-server5050

0 Stars in the last 47 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The web layer is a transport detail, not the application

The central idea section states the intent in the first person and then immediately sets a boundary. The goal was an interactive REST service on top of an existing distributed computation application, serving three named use cases: load a trained model into the session and answer a prediction query quickly, keep large data cached in the cluster and expose an endpoint to query it, and run recurring jobs with varying parameters. Then the boundary: the core of the application is not primarily a web application or a browser interaction, but a REST service performing cluster computation. That framing is the whole design. The HTTP server exists so the jobs are reachable, not because the project is about serving HTTP, and every subsequent choice follows from that.

Two of the four demo routes actually touch the cluster

Four routes are configured to demonstrate the pattern, and they differ in what they prove. One returns a fixed greeting and exists only to show the server is listening on a port. One asks the shared session for its version and returns it, which proves the session is reachable from a request handler rather than only at startup. One reports how many streams are currently active, which is the route that shows long-lived cluster state being read from a request. The fourth submits a job that counts elements in a sequence, described as random, which is the only route that demonstrates the thing the project exists for: a request triggering actual computation rather than reading a cached answer.

Akka HTTP was chosen so it would not be the application

The second section is the argument for the web framework and it is a short one, but it is the load bearing sentence of the whole design. The claim is that with this server you do not build your application on top of it; you build your application on top of whatever makes sense for the domain and use the HTTP library only where you need HTTP integration. That framing is the opposite of how most people pick a web framework, and it is why the choice is presented as a fit rather than a preference. If you take the design idea and drop the library, you still have the useful part: the transport should be interchangeable. If you adopt the library as your architectural centre, you have inverted the argument the project was making.

Build and run both go through Maven, and the run is not a jar

The build step is one command and the execution step is one command, and they share a tool. The project is a Maven module built from a single descriptor file with a source tree beside it, and the execution instruction runs the main class through the exec plugin rather than launching a packaged artefact. That is worth noticing because the help text produced by the program itself advertises something else: its usage line names a packaged jar and the packaging tool for distributed submission, complete with an options block. So the program documents one invocation style while the page documents another. Neither is wrong, and you may well want the packaged form in a cluster, but it means the documented path and the program's own help do not agree about how you are meant to start it.

code
mvn clean install
code
mvn exec:java
code
mvn exec:java -Dexec.args="--help"

Configuration lives in one file, and the examples use long flags

Two mechanisms are offered for changing defaults and neither is hidden. The first is to edit the application configuration file in the resources directory and rebuild. The second is to pass values on the command line, and the example shows three of them at once: the cluster master, the application name, and the port the HTTP layer should listen on. The help output confirms what the program needs by naming three parameters: the web port to bind, the cluster master, and the application name. Two details will bite you. The help output lists short flags while the example passes long ones, so both forms exist and only the short ones are shown. And the displayed options block is cut off partway through the application name description, so the full flag list is not visible on the page at all.

code
mvn exec:java -Dexec.args="--master <master> --name <spark-app-name> --akkaHttpPort <port-to-which-akka-should-listen-to>"

The stated stack is two major versions behind current

The build section names three things and their versions: a Scala language version, a Spark version, and the HTTP library. The application identifies itself in its own help text with the same Spark version, so the numbers are consistent rather than aspirational. What they represent is a demonstration from a few years ago, and the repository has not been touched since a push in July 2023, with no releases at all. There is nothing wrong with reading old code to learn a shape. The practical cautions are ordinary ones: an unreleased module pinned to an old engine major version will need dependency work before it compiles against anything current, and the four-entry repository has no tests to tell you when you have broken something.

The routing diagram is announced and then missing

The architecture section ends with a sentence that introduces a picture illustrating how a request is routed, and the picture is not on the page as it reaches you. That is a small thing but it is the part that would have explained the design, and its absence means the routing has to be inferred from the four route definitions and the framework argument. The rest of the repository is equally spare: a gitignore, the readme, the Maven descriptor and a source tree. There is no licence file, no contributing guide and no documentation directory. If you want to understand where the request handlers sit relative to the session and the jobs, the source is the only place that answer exists, and at that size reading it is cheaper than searching for documentation that was never written.

The cluster master option already covers local execution

One small detail in the options block is worth pulling out because it tells you how the demonstration is meant to be tried. The master option accepts a URL for a standalone cluster, a URL for a Mesos cluster, a YARN value, or a local value, and the default is local. So the whole thing runs on one machine with no cluster by default, which is what makes the four-route demo something you can start in a minute rather than provision anything. The application name option exists alongside it because a distributed engine wants a name to show in its interface. The combination is a sensible minimum: no cluster to stand up for a first look, and a real cluster to point at when the demonstration has taught you what you are demonstrating.

code
Usage: spark-submit spark-as-service-using-embedded-server.jar [options]
  Options:
  -h, --help
  -m, --master <master_url>                    spark://host:port, mesos://host:port, yarn, or local. Default: local

Editorial conclusion

Read this as a shape rather than a dependency. The idea it demonstrates, that you build on top of your computation engine and bolt an HTTP layer on for transport only, is the part that transfers; the code itself is pinned to a Spark major version from several years ago and has not moved since July 2023. Two things to check if you are tempted to build on it. That the Maven invocations in the documentation are what you actually want, since the help banner advertises a packaged jar while the documented run path goes through the plugin. And that you have decided where configuration lives, because the module offers a config file, long command line flags and short flags, and they are not spelled identically.

Frequently asked questions

Is Apache Spark still relevant?

The repository does not address that question. What it offers is a demonstration pinned to a specific Spark major version and an older Scala version, with the most recent recorded push to the default branch dated July 2023 and no tagged releases at all.

What are embedded servers?

In this project's usage it means the HTTP server runs inside the application process rather than in a separate container or behind a standalone server. The stated benefit is that you build your application on top of whatever suits the domain and use the HTTP library only for the integration, rather than letting the web framework define your architecture.

Is Spark Streaming deprecated?

Nothing here discusses deprecation of anything. The closest the page comes is one of its four demo routes, which reports how many streaming jobs are currently active by querying the shared session at request time, and the cluster master option which accepts a standalone, Mesos or YARN value as well as a local default.

Is DuckDB faster than Spark?

The repository makes no comparison with any other system and does not mention that one. Its stated purpose is narrower: exposing cluster computation, whether that is a cached data set queried repeatedly, a trained model answering prediction requests, or a recurring job with varying parameters, over a REST interface.

Official sources

  1. Official README
  2. Project repository
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/spoddutur-spark-as-service-using-embedded-server.svg)](https://hysenlabs.com/projects/spoddutur-spark-as-service-using-embedded-server)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/spoddutur-spark-as-service-using-embedded-server.svg)](https://hysenlabs.com/projects/spoddutur-spark-as-service-using-embedded-server)