# ServiceFramework is a Rails-style MVC framework for mobile backends

> ServiceFramework is a Java MVC framework built for mobile application backends, with an ActiveRecord-style model layer over MongoDB and MySQL, a filter-based controller layer, built-in monitoring and rate limiting, and a Scala 2.13 build that emits Java 8 bytecode.

**allwefantasy/ServiceFramework** — Java MVC framework, agile, fast, rich domain model, made especially for server side of mobile application (一个敏捷，快速，富领域模型的Java MVC 框架，专为 移动应用后端量身定做)

- Repository: https://github.com/allwefantasy/ServiceFramework
- Stars: 547 · Forks: 251
- Language: Java
- License: not declared
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/allwefantasy-serviceframework

## A Java MVC framework positioned for mobile application backends

ServiceFramework is a Java MVC framework whose stated target is the server side of mobile applications, and the project describes itself as agile, fast, with a rich domain model. The ambition is stated in a comparison rather than a benchmark: the development efficiency is said to be comparable to Rails, which is a claim about developer experience rather than a measurement.

The implementation is not pure Java. The default build is Scala 2.13.16 producing Java 8 bytecode, and the top-level directory names show why: serviceframework-web, serviceframework-common, serviceframework-dispatcher, serviceframework-jetty-9-server, serviceframework-mongo and serviceframework-orm are separate modules, with the ORM and the MongoDB support split out from the web layer. There is also a client directory, an apps directory, a script directory and a jar directory.

The practical reading is that this is a framework with its own opinions about how a backend should be shaped, assembled from components the author has run in production, rather than a thin layer over a servlet container. The Jetty 9 module in the name is a hint about the server it expects.

## The build is Maven, and the Scala profiles are not all validated

Building from source is the standard two-step Maven flow, with the repository cloned and then installed:

```bash
    git clone git@github.com:allwefantasy/ServiceFramework.git
    mvn install
```

What that produces is a JAR built with Scala 2.13.16 and targeting Java 8 bytecode, deployed on the classpath. The README is unusually specific about the boundaries of that matrix. The 2.11 and 2.12 Scala profiles still exist, invoked with -Pscala-2.11 and -Pscala-2.12, but the project says they have not entered the accepted JDK 8 and JDK 17 matrix, and that the local JDK paths and the commands used for that matrix are documented in docs/jdk-compatibility.md. Behaviour changes in bytecode enhancement, along with migration notes, live in docs/serviceframework-bytecode-migration.md.

That is a real warning for anyone who plans to pin an old Scala line. The profile exists, so the build will accept it, but the project is telling you it is outside what has been validated. The second point to check is the published artifact: the Maven coordinates given are net.csdn with artifactId serviceframework-web_2.13 and version 2.0.9, described as the current source tree coordinates and the JAR produced by the default JDK 8 and JDK 17 matrix, while the _2.11 variant is not part of that acceptance.

## The model layer reads like ActiveRecord over MongoDB and MySQL

The first listed feature is an ActiveRecord-style model layer supporting both MongoDB and MySQL. The example in the README is a static finder that returns a collection, calling where with a map of field names and values and then fetching the result, which is the shape of an ORM that treats a static call as a query rather than as a method on an instance.

Because both databases are supported, the choice is made in configuration rather than in code. The quick start asks you to edit config/application.yaml, and the datasource block shows three entries: mysql with a host, port, database, username and password, a mongodb entry with a host, port and database, and a redis entry. Each carries a disable flag, and the instruction is that if you use MySQL you need to disable MongoDB and the other way round. The redis entry ships with disable: true.

There is a small documentation wrinkle worth knowing about before you start, because it will cost you a search later. The configuration section says the project root needs config/application.yml and config/logging.yml, while the quick start step refers to editing config/application.yaml. Two different spellings of the application config appear in the same document, so check which one the code in the repository actually reads before you create files.

## Controllers use a filter DSL and the framework skips the container

The controller layer is described as completely redesigned, with many convenience functions, and the README points at an innovative filter design. The example registers a filter in a static block: beforeFilter with a validation method name and a map of only the actions it should apply to, here the push method, so the filter intercepts that call and leaves the rest alone.

Two further points decide how much of your own code you have to write. Most objects are managed automatically through IoC, with injection handled by a single annotation on the field, so a service does not need a factory or a lookup. And the framework does not depend on a container, which the project presents as the reason unit testing is simple, with the claim that from an action down to a service the test code can be kept to a minimum.

That last property is the one to test in your own project first. A container-free design means less wiring, but it also means the lifecycle of services is something the framework defines rather than something you configure, and the interaction between IoC-managed services and hand-built ones is where the surprises usually live.

## Monitoring, QPS limits and degradation are part of the framework

The framework treats self-protection as a feature rather than as an operational add-on, on the reasoning that a backend service without a self-protection mechanism becomes overloaded and unavailable. The list of what is instrumented is concrete: queries per second per endpoint, average response time per endpoint, and call counts, which for HTTP means a breakdown by status code, plus a built-in HTTP endpoint that returns this state as JSON.

The response-time data is what makes the rest work. By watching average response time per endpoint and doing some capacity planning, you can adjust the QPS limit dynamically, so the service sheds load before it fails, and both the configuration and the built-in HTTP interface are ways to do that. Degradation and rate limiting are described together in the feature list, which in practice means a limit that is enforced rather than only reported.

Earlier versions of the framework leaned on logs instead, and the README lists what was printed: the request URL, the total request duration, the database duration if there was one, and the response status code, with the suggestion that shell scripts over those logs can produce the statistics. The built-in metrics interface is the successor to that, and the trade is that a log-scraping approach stays available for environments where you do not want to expose the metrics endpoint.

## Thrift and RESTful on one configuration, with Velocity for pages

Serving both a Thrift and a RESTful interface is described as needing simple configuration. The example yaml block shows an http section with a port and a disable flag, and a thrift section with its own disable flag, a services map where a service implementation is bound to a port with a minimum and maximum thread count, and a servers list holding the load targets. The two stacks can therefore be exposed side by side from one process, which is the arrangement a mobile client plus an internal RPC consumer usually wants.

Pages are handled by Velocity, and the README says the template can access all instance variables and the methods of helper classes, with template configuration supported. The quick start creates template/tag/hello.vm, and the controller example renders with ViewType.html.

The routing annotation is what ties it together, with @At carrying a path and a list of request methods, and the same annotation used for a page route that returns HTML, which means a controller can serve an HTML view and a JSON API from the same class. Note that the page layer is part of the framework rather than a separate template engine you can swap, so a team without Velocity experience inherits a specific template syntax and a specific static asset story.

## One interface definition makes HTTP calls look like RPC

Since version 1.2 the project has integrated Dubbo and adds a RestProtocol, so that an existing HTTP service can be called as if it were an RPC service, with the work reduced to defining a single interface. The example defines a controller with an @At annotation and a method returning HttpTransportService.SResponse, and the calling side invokes that method directly and reads the content. A provider can define several methods against the same path, each taking a subset of the parameters, and the README says that makes the interface easier for the caller to use.

The same shape works for third-party HTTP APIs when Dubbo is not in play. You declare a trait with an @At path and method list, and the client is built with AggregateRestClient.buildClient, taking the host and ports, a strategy object that decides how the backend is called, and the HTTP request implementation. The strategy is where you express whether the calls are round-robin over the hosts or follow some other logic, and the project notes that calls made this way produce trace logs.

The difference from calling a URL directly is that the call sites get a typed signature, and the transport details move into the strategy object. The cost is an extra layer of code to understand, and a dependency on the annotation and client conventions of the framework.

## The quick start ends with a database row and an action test

The walkthrough in the README is eleven steps, and it is worth reading as a description of the intended project shape. Step 1 clones the repository and step 2 imports it into an IDE. Step 3 edits the datasource configuration. Step 4 imports the shipped sql/wow.sql into MySQL. Step 5 creates a Tag class in com.example.model that extends Model and does nothing else, which is the extent of the domain model you need for a first request. Step 6 creates a TagController in com.example.controller.http that extends ApplicationController, handles a GET path, creates a Tag with a name, saves it and renders it as an HTML view.

Step 7 creates the Velocity template, step 8 creates the start class, where a loader is pointed at the application class before the framework's main method runs, and step 9 runs it. Step 10 opens http://127.0.0.1:9002/hello in a browser and then checks the database to confirm the tag table has a row, which is the moment the model layer, the controller, the view and the database are all proven at once. Step 11 covers the action test, where the test environment is set up by editing runner.DynamicSuite and adding a loader call at the start of its initEnv method.

A separate example project, godear, is an RSS subscription system that shows a wider set of typical usages, including how to build a paged interface that is not a JSON REST API.

## Conclusion

ServiceFramework fits a team building a mobile application backend in Java that wants a Rails-style model layer, HTTP and Thrift on one port configuration, and monitoring with adjustable QPS limits without assembling those pieces separately. It does not fit a project that needs a maintained release line, since the repository publishes no GitHub releases and states no licence, or one that needs the 2.11 or 2.12 Scala profiles, which the project says are not in the accepted JDK matrix. Before you build on it, check three things: that the net.csdn serviceframework-web_2.13 coordinates at version 2.0.9 match the JDK 8 and JDK 17 matrix the project describes, that the config/application.yml and config/logging.yml files your deployment expects exist, since the quick start refers to a differently spelled config/application.yaml, and that the Velocity template layer at template/tag/hello.vm is a dependency you want, since page rendering is part of the framework rather than an add-on. The last push was on 2026-09-26.

## FAQ

### How do I build ServiceFramework from source?

Clone the repository and run a Maven install, so `git clone git@github.com:allwefantasy/ServiceFramework.git` followed by `mvn install`. The default build is Scala 2.13.16 producing Java 8 bytecode deployed on the classpath.

### Which Maven coordinates should I depend on?

The README gives groupId net.csdn, artifactId serviceframework-web_2.13 and version 2.0.9, described as the current source tree coordinates and the JAR produced by the default JDK 8 and JDK 17 matrix. The _2.11 variant is not part of that accepted matrix.

### Does ServiceFramework support both MongoDB and MySQL?

Yes. The model layer is ActiveRecord-style and supports both, and the datasource configuration has entries for mysql, mongodb and redis, each with a disable flag. The quick start notes that if you use MySQL you disable MongoDB and the other way round.

### Can ServiceFramework serve Thrift and RESTful at the same time?

Yes, with configuration. The example yaml shows an http block with a port and a disable flag, and a thrift block with a services map binding an implementation to a port with minimum and maximum thread counts, plus a servers list of load targets.

### Does ServiceFramework have rate limiting and monitoring?

Yes. It monitors queries per second and average response time per endpoint, counts calls, and exposes the state as JSON through a built-in HTTP endpoint. QPS limits can be adjusted dynamically using that data, and degradation and rate limiting are part of the same feature set.

## Sources

- [allwefantasy/ServiceFramework on GitHub](https://github.com/allwefantasy/ServiceFramework)
- [Issues](https://github.com/allwefantasy/ServiceFramework/issues)
- [README](https://github.com/allwefantasy/ServiceFramework/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/allwefantasy-serviceframework
