RESTHeart logo

RESTHeart

The Open Source Backend for MongoDB.

Instant REST, GraphQL and WebSocket APIs. No backend code.

Built-in authentication and authorization. Declarative, zero boilerplate.

Need custom logic? Extend it in Java, Kotlin, JavaScript or TypeScript.

Plus Sophia, the AI assistant: chat with the docs or vibe code via MCP.

Fully managed, no installation required • Or run it yourself — free and open source

Run RESTHeart with MongoDB:

curl -O https://raw.githubusercontent.com/\
SoftInstigate/restheart/master/docker-compose.yml
docker compose up

Your MongoDB, instantly an API:

# read, write and query documents — no backend code
curl -X POST localhost:8080/inventory \
  -d '{"item":"card", "qty":15}'
curl localhost:8080/inventory

More ways to run it →

Get Started

MongoDB REST API Tutorial MongoDB GraphQL API Tutorial Framework Tutorial Auth Tutorial

Setup instructions included in each tutorial

RESTHeart Features

MongoDB's best friend

RESTHeart unlocks all the features of MongoDB via REST, GraphQL and WebSocket APIs.

Also supports Mongo Atlas, FerretDB, AWS DocumentDB, and Azure Cosmos DB

Declarative Access Control

RESTHeart provides a powerful and battle-tested security layer that keeps your application secure without coding.

User Accounts

The restheart-accounts plugin covers the full user lifecycle: registration, email verification, password reset, team invitations and Google social login — all configurable, no code.

REST Data API

Read, write and search JSON documents with HTTP requests without coding; specify MongoDB queries and projection options; deal with large result sets with automatic pagination.

GraphQL Data API

The GraphQL plugin works side by side with the REST plugin to get an unified API to build modern applications. GraphQL applications are configured through an API without coding.

WebSocket Data API

The WebSocket API notifies clients of data changes in real time and supports thousands of connected clients. Data streams are configured through an API without coding.

Development Framework

Build microservices in Java, Kotlin, JavaScript or TypeScript with a set of simple yet robust building blocks: Service, Provider, Interceptor, and Initializer.

Container friendly

RESTHeart is available as a Docker image and tailored for the GraalVM to build lightweight native images with instant startup time, low memory footprint.

Vibe Coding with RESTHeart

RESTHeart comes with Sophia, its AI assistant. Two ways to use it:

💬 Just ask

Chat with Sophia in your browser and get instant answers about RESTHeart. No setup needed.

Chat with Sophia

⚡ Vibe code in your editor

Connect Claude Code, Cursor or VS Code to the RESTHeart MCP server: your AI answers questions, writes working code and configures your backend.

claude mcp add --transport http sophia-restheart \
  https://api.bysophia.ai/mcp/restheart

Setup for Claude Desktop, VS Code, Zed and more →

Data API

Query documents from the command line with httpie.

The GET request has two query parameters: filter to apply a query and pagesize to limit the response to one document.
Here we use the brilliant httpie, a modern command line HTTP client.

More examples
$ http -b GET https://demo.restheart.org/messages'?filter={"from":"Bob"}&pagesize=1'

[
  {
    "_id": { "$oid": "5c50963e477870eb8258fa68" },
    "from": "Bob",
    "message": "was here"
  }
]

Query documents from the command line with cURL.

The GET request has two query parameters: filter to apply a query (that needs to be encoded with `-G --data-urlencode` option since it contains the curly brackets) and pagesize to limit the response to one document.
Here we use the immortal cURL!

More examples
$ curl -G --data-urlencode 'filter={"from":"Bob"}' \
  https://demo.restheart.org/messages?pagesize=1

[
  {
    "_id": { "$oid": "5c50963e477870eb8258fa68" },
    "from": "Bob",
    "message": "was here"
  }
]

Query documents with JavaScript.

The GET request has two query parameters: filter to apply a query and pagesize to limit the response to one document.
Here we use the fetch API.

Run it
const url = encodeURI('https://demo.restheart.org/messages?filter={"from":"Bob"}&pagesize=1');

fetch(url)
  .then(response => response.json())
  .then(json => JSON.stringify(json, null, 2))
  .then(docs => console.log(docs));

Query documents with Java.

The GET request has two query parameters: filter to apply a query and pagesize to limit the response to one document.
Here we use the unirest java http library.

More examples
public void printOutMessages() throws UnirestException {
  var resp = Unirest.get("https://demo.restheart.org/messages")
    .queryString("filter", "{'from':'Bob'}")
    .queryString("pagesize", "1")
    .asJson();
  
  // print out each message
  resp.getBody().getArray().forEach(msg -> 
    System.out.println(msg.toString())
  );
}

Query documents with Python.

The GET request has two query parameters: filter to apply a query and pagesize to limit the response to one document.
This example uses the popular requests library.

More examples
import requests
import json

url = "https://demo.restheart.org/messages"
params = {
    "filter": '{"from":"Bob"}',
    "pagesize": "1"
}

response = requests.get(url, params=params)
data = response.json()

print(json.dumps(data, indent=2))

Query documents with Swift.

The GET request has two query parameters: filter to apply a query and pagesize to limit the response to one document.
This example uses modern Swift with async/await (Swift 5.5+).

More examples
import Foundation

func fetchMessages() async throws {
  var components = URLComponents(string: "https://demo.restheart.org/messages")
  components?.queryItems = [
    URLQueryItem(name: "pagesize", value: "1"),
    URLQueryItem(name: "filter", value: "{\"from\":\"Bob\"}")
  ]
  
  guard let url = components?.url else {
    throw URLError(.badURL)
  }
  
  let (data, _) = try await URLSession.shared.data(from: url)
  let json = try JSONSerialization.jsonObject(with: data)
  print(json)
}

// Usage
Task {
  try await fetchMessages()
}

Polyglot Framework

Implement web services in minutes.

Implement a simple interface and deploy the web service by copying its jar file into the plugins directory.

See it on GitHub More examples
@RegisterPlugin(name="greetings", description="just another Hello World")
public class GreeterService implements JsonService {

  @Override
  public void handle(JsonRequest req, JsonResponse res) {
    switch(req.getMethod()) {
      case GET ->
        res.setContent(object().put("message", "Hello World!"));
      case OPTIONS ->
        handleOptions(req);
      default ->
        res.setStatusCode(HttpStatus.SC_METHOD_NOT_ALLOWED);
    }
  }
}

Implement plugins in Kotlin.

You can use Java and Kotlin to implement plugins.

Kotlin Service example
@RegisterPlugin(name="kotlinGreeterService", description="just another Hello World")
class GreeterService : JsonService {

  override fun handle(req: JsonRequest, res: JsonResponse) {
    when(req.method) {
      METHOD.GET ->
        res.content = obj().put("msg", "Hello World").get()
      METHOD.OPTIONS ->
        handleOptions(req)
      else ->
        res.setStatusCode(HttpStatus.SC_METHOD_NOT_ALLOWED)
    }
  }
}

Snoop and modify requests at different stages of their lifecycle.

This interceptor applies to requests of the hello web service adding a timestamp to the response content.
Interceptor can be executed at different points of the request as defined by the interceptPoint parameter of the annotation RegisterPlugin

More examples
@RegisterPlugin(
  name = "helloInterceptor",
  description = "add a timestamp to the response of /greetings",
  interceptPoint = InterceptPoint.RESPONSE)
public class HelloInterceptor implements JsonInterceptor {

  @Override
  public void handle(JsonRequest req, JsonResponse res) {
    res.getContent()
      .getAsJsonObject()
      .addProperty("timestamp", Instant.now().toString());
  }

  @Override
  public boolean resolve(JsonRequest req, JsonResponse res) {
    return req.isHandledBy("greetings");
  }
}

Implement plugins in JavaScript.

This is yet another Hello World web service.
Running RESTHeart on the GraalVM allows you to deploy JavaScript Services and Interceptors.

More examples
export const options = {
  name: "helloWorldService",
  description: "just another Hello World",
  uri: "/hello"
}

export function handle(req, res) {
  res.setContent(JSON.stringify({ msg: 'Hello World' }));
  res.setContentTypeAsJson();
}