JavaShot Tutorial: Build Microservices in MinutesMicroservices have reshaped how modern applications are designed, deployed, and scaled. Java remains one of the most popular languages for building backend systems, and JavaShot is an emerging lightweight framework that aims to make creating microservices fast, simple, and pragmatic. This tutorial walks you through building a production-ready microservice with JavaShot in minutes, covering project setup, core concepts, REST endpoints, data access, configuration, testing, containerization, and deployment tips.
What is JavaShot?
JavaShot is a minimal, developer-friendly Java framework focused on microservices. It emphasizes:
- Simplicity: minimal boilerplate and conventions that favor explicitness.
- Speed: fast startup time and low memory footprint.
- Modularity: small kernel with optional extensions for persistence, messaging, and observability.
- Developer experience: intuitive APIs, built-in dev server, and hot-reload support.
Think of JavaShot as a “micro” alternative to larger frameworks—giving you core microservice tools without the weight.
Prerequisites
Before you begin, make sure you have:
- Java 17 or later installed.
- Maven or Gradle (examples below use Maven).
- Docker (for containerization section).
- Basic knowledge of Java and RESTful APIs.
Project setup (Maven)
Create a new Maven project and add the JavaShot starter dependency. Below is a sample pom.xml
snippet:
<project xmlns="http://maven.apache.org/POM/4.0.0" ...> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>javashot-demo</artifactId> <version>0.1.0</version> <properties> <java.version>17</java.version> </properties> <dependencies> <!-- JavaShot core --> <dependency> <groupId>io.javashot</groupId> <artifactId>javashot-core</artifactId> <version>1.2.0</version> </dependency> <!-- JSON binding --> <dependency> <groupId>io.javashot</groupId> <artifactId>javashot-jackson</artifactId> <version>1.2.0</version> </dependency> <!-- Optional: persistence --> <dependency> <groupId>io.javashot</groupId> <artifactId>javashot-data-jpa</artifactId> <version>1.2.0</version> </dependency> <!-- H2 for local testing --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <!-- Testing --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.9.3</version> <scope>test</scope> </dependency> </dependencies> </project>
Application entry point
Create the main application class to bootstrap JavaShot:
package com.example.javashot; import io.javashot.JSApplication; public class Application { public static void main(String[] args) { JSApplication app = new JSApplication.Builder() .scanPackages("com.example.javashot") .build(); app.start(args); } }
JSApplication performs component scanning, registers controllers, and configures the HTTP server.
Defining a REST controller
JavaShot controllers are POJOs annotated with @JSController and map HTTP routes using @Route.
package com.example.javashot.controller; import io.javashot.annotations.JSController; import io.javashot.annotations.Route; import io.javashot.http.Response; @JSController public class GreetingController { @Route(path = "/hello", method = "GET") public Response hello() { return Response.ok().json(Map.of("message", "Hello from JavaShot!")); } }
This creates a GET /hello endpoint returning JSON.
Dependency injection and services
JavaShot provides a lightweight DI container. Use @JSService for singleton services and inject with constructor parameters.
package com.example.javashot.service; import io.javashot.annotations.JSService; import com.example.javashot.repository.UserRepository; @JSService public class UserService { private final UserRepository repo; public UserService(UserRepository repo) { this.repo = repo; } public User createUser(String name) { return repo.save(new User(name)); } }
Data layer with JPA
JavaShot integrates with standard JPA. Define an entity and repository:
@Entity public class User { @Id @GeneratedValue private Long id; private String name; // getters/setters }
Repository using JavaShot’s repository support:
@JSRepository public interface UserRepository extends JpaRepository<User, Long> {}
Use in controller:
@JSController public class UserController { private final UserService userService; public UserController(UserService userService) { this.userService = userService; } @Route(path="/users", method="POST") public Response createUser(Request req) { UserDto dto = req.body(UserDto.class); User user = userService.createUser(dto.getName()); return Response.created().json(user); } }
Configuration
JavaShot reads configuration from application.yml or environment variables. Example application.yml
:
server: port: 8080 datasource: url: jdbc:h2:mem:demo;DB_CLOSE_DELAY=-1 username: sa password:
Override with environment variables like SERVER_PORT=8081.
Hot reload and developer experience
Run in dev mode to get hot reload and detailed logs:
mvn -Denv=dev javashot:run
Hot reload watches classpath and restarts the minimal parts necessary for fast feedback.
Testing
JavaShot supports unit and integration testing. Example JUnit test for GreetingController:
@JSRunWith public class GreetingControllerTest { @Test void helloReturnsGreeting() { TestClient client = TestClient.create(); var resp = client.get("/hello"); assertEquals(200, resp.getStatus()); assertEquals("Hello from JavaShot!", resp.json().getString("message")); } }
Containerization (Docker)
Sample Dockerfile for a small runtime image:
FROM eclipse-temurin:17-jre-jammy WORKDIR /app COPY target/javashot-demo.jar app.jar EXPOSE 8080 ENTRYPOINT ["java","-jar","/app/app.jar"]
Build & run:
docker build -t javashot-demo . docker run -p 8080:8080 javashot-demo
Observability and metrics
Add JavaShot’s metrics module to expose Prometheus metrics and distributed tracing support with OpenTelemetry. Configure via application.yml:
observability: metrics: prometheus tracing: otel
Deployment tips
- Use readiness and liveness probes in Kubernetes.
- Keep services small and single-responsibility.
- Use circuit breakers for remote calls.
- Automate CI/CD with small image builds and multi-stage Dockerfiles.
Example: Building a Todo microservice in ~10 minutes
- Generate Maven project with JavaShot starter.
- Add User/Todo entity and repository.
- Implement TodoService and TodoController with CRUD endpoints.
- Configure H2 for dev and Postgres for production.
- Run
mvn package
anddocker build
then deploy.
Conclusion
JavaShot makes it straightforward to build, test, and deploy microservices quickly by combining a minimal core, familiar APIs (JPA, JSON), and a strong developer experience. With hot-reload, simple DI, and easy integration points for metrics and tracing, you can prototype services in minutes and scale them into production systems with common best practices.
Leave a Reply