Skip to main content
Contributions are welcome. If you find a bug or want to propose a feature, open an issue on GitHub first — it helps coordinate effort and avoid duplicate work.

Local setup

1

Fork and clone the repository

Fork the repository on GitHub, then clone your fork:
git clone https://github.com/YOUR_USERNAME/apple-maps-java.git
cd apple-maps-java
2

Configure your token

Copy the example environment file and add your Apple Maps Server API token:
cp .env-example .env
Open .env and set:
APPLE_MAPS_TOKEN=your_token_here
3

Build the project

./gradlew build
A successful build compiles all sources, runs unit tests, and checks code style.
4

Create a feature branch

git checkout -b my-feature

Build commands

The project uses Gradle. A Makefile provides shortcuts for the most common tasks.
# Full build (compile + unit tests + style check)
./gradlew build

# Unit tests only
./gradlew test

# Integration tests (requires APPLE_MAPS_TOKEN)
./gradlew testDetail

# Check code style
./gradlew spotlessCheck

# Auto-fix code style
./gradlew spotlessApply

# Lint (all checks)
./gradlew check

# Clean build outputs
./gradlew clean

Code style

This project uses Spotless to enforce consistent formatting. Before opening a PR, verify your changes pass the style check:
./gradlew spotlessCheck
If the check fails, auto-fix the formatting:
./gradlew spotlessApply
Then re-run the check to confirm it passes before committing.

Architecture overview

The codebase follows clean architecture with a strict dependency rule: dependencies point inward. Framework imports never appear in the domain layer.
src/main/java/com/williamcallahan/applemaps/
├── AppleMaps.java              # Public entry point — the main SDK class
├── domain/                     # Pure business logic, no framework imports
│   ├── model/                  # Immutable value objects and response records
│   └── request/                # Typed request input builders
├── adapters/                   # Infrastructure implementations
│   ├── mapsserver/             # HTTP client for the Apple Maps Server API
│   └── jackson/                # JSON serialization / deserialization
└── cli/                        # CLI runner (AppleMapsCli.java)
PackageResponsibility
domain/Pure Java logic. Immutable records with constructor validation. No Spring, no Jackson, no HTTP.
adapters/Implements ports defined by the domain. Contains all HTTP and Jackson-specific code.
cli/Parses command-line arguments and delegates to the SDK via AppleMaps.java.
AppleMaps.javaThe single public entry point for library consumers.
When adding a new API operation, start in domain/ with typed request and response records, then add the HTTP adapter in adapters/mapsserver/, and finally expose it on AppleMaps.java.

PR guidelines

  • One change per PR. Keep pull requests focused on a single bug fix or feature.
  • Add tests. New functionality requires corresponding tests before the PR can be merged. Unit tests go in classes ending with Test; integration tests go in classes ending with IT.
  • Pass the build. Run ./gradlew build locally and confirm it succeeds before pushing.
  • Update documentation. If your change affects public behavior, update the relevant docs pages.
  • Descriptive commit messages. Write messages that explain why the change is being made, not just what was changed.

Reporting issues

When opening an issue, include:
  • A clear description of the problem
  • Steps to reproduce
  • Expected vs. actual behavior
  • Library version and Java version