RESTHeart:基于MongoDB快速构建API

在本文中,我们简要介绍了 RESTHeart 及其功能。使用这个框架还可以实现更多功能,因此下次您需要创建 HTTP API 时,不妨参考一下。

RESTHeart是一个基于 Java 的框架,它允许我们在MongoDB之上快速构建 HTTP API 。它使我们能够以最少的设置将 MongoDB 集合公开为 REST 和 GraphQL API,同时仍然允许我们根据需要进行控制。

在本教程中,我们将快速了解 RESTHeart API 框架。

什么是 RESTHeart?
RESTHeart 提供了一个基于 MongoDB 构建的开源 API 服务器。它会自动将我们的集合公开为 REST 和 GraphQL 端点,让我们无需编写任何代码即可创建 API。

开箱即用,我们得到:

  • 通过 HTTP 和 GraphQL 提供全面的 CRUD 支持
  • 基于角色的访问控制和身份验证
  • 用于用户和角色管理的内置管理 API
  • 通过 Java 插件或配置实现自定义行为的扩展点
这为基于 HTTP 的 API 构建提供了零代码解决方案,从而实现快速实施。如有需要,我们还可以集成自定义 Java 代码,以实现开箱即用无法实现的额外功能。

运行 RESTHeart
如果我们想在本地运行 RESTHeart,我们需要安装 Java 21 或更高版本。此外,我们还需要下载RESTHeart 发行版。下载并解压后,我们可以通过运行restheart.jar立即启动该服务:

$ java -jar restheart.jar
17:39:17.943 [main] INFO  org.restheart.Bootstrapper - Starting RESTHeart instance default
17:39:17.945 [main] INFO  org.restheart.Bootstrapper - Version 8.4.0
.....
17:39:19.188 [main] INFO  org.restheart.Bootstrapper - RESTHeart started

无需任何配置,这将尝试使用可在 127.0.0.1:27017 上访问且不需要任何凭据的 MongoDB。

或者,我们提供了一个 Docker 镜像,可用于运行 RESTHeart。这也使我们能够运行包含 MongoDB 的Docker Compose设置,以便所有组件都可以作为单个堆栈启动。为此,我们需要一个docker-compose.yml文件:

$ cat docker-compose.yml
services:
  mongodb:
    image: mongo:latest
    container_name: mongodb
    ports:
      - "27017:27017"
    networks:
      - mongo-restheart-network
  restheart:
    image: softinstigate/restheart:latest
    container_name: restheart
    ports:
      -
"8080:8080"
    networks:
      - mongo-restheart-network
    environment:
      MONGO_URI: mongodb:
//mongodb:27017
    depends_on:
      - mongodb
networks:
  mongo-restheart-network:
    driver: bridge

然后我们可以使用docker compose启动服务,然后就可以开始了:

$ docker compose up -d
[+] Running 3/3
   Network restheart_mongo-restheart-network  Created
   Container mongodb                          Started
   Container restheart                        Started

一旦一切开始,我们就可以通过调用服务器上的/ping端点来测试设置:

$ curl localhost:8080/ping
{"message": "Greetings from RESTHeart!", "client_ip": "192.168.65.1", "host": "localhost:8080", "version": "8.4.0"}

至此,我们已经拥有了功能齐全的服务。

身份验证和用户
对我们的 RESTHeart 服务进行的大部分 API 调用都需要身份验证,RESTHeart 会自动处理。例如,如果我们向根资源发出未经身份验证的请求,则会收到 HTTP 401 Unauthorized响应:

$ curl -v localhost:8080/
> GET / HTTP/1.1
>
< HTTP/1.1 401 Unauthorized
< WWW-Authenticate: Basic realm="RESTHeart Realm"

默认情况下,所有用户记录都存储在 MongoDB 数据库的users集合中。如果我们在一个空数据库中启动 RESTHeart,则会自动创建该集合,并向其中添加一个管理员用户:


虽然密码已安全散列且无法查看,但默认凭据由用户名admin和密码secret组成。我们现在可以使用以下凭据再次发出请求:

$ curl -v -u admin:secret localhost:8080/
> GET / HTTP/1.1
> Authorization: Basic YWRtaW46c2VjcmV0
>
< HTTP/1.1 200 OK
< Content-Type: application/json
<
["acl", "users"]

现在一切正常,我们得到了预期的响应。

使用 RESTHeart 进行 CRUD 操作
RESTHeart 自动从我们的数据库中公开 MongoDB 集合,以便我们可以通过标准 REST 和 GraphQL API 以最小的努力读取和操作它们。

1. REST API
RESTHeart 公开了一个 REST API,其中包含针对每个集合的一组标准 URL 模式:

  • GET / – 搜索集合
  • GET // – 从集合中获取记录
  • POST / – 在集合中创建新记录
  • PUT // – 替换集合中的一条记录
  • PATCH // – 修补集合中的记录
  • DELETE // – 从集合中删除一条记录
我们还可以通过发送特殊请求来创建新集合。为此,我们直接向集合的端点发出PUT请求:

$ curl -v -u admin:secret -X PUT localhost:8080/posts
> PUT /posts HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 0
<

一旦我们有一个集合,我们就使用POST请求在其中创建一个新记录:

$ curl -v -u admin:secret -X POST localhost:8080/posts -d '{"title": "Introduction to RESTHeart", "author": "Baeldung"}' -H "Content-Type: application/json"
> POST /posts HTTP/1.1
> Content-Type: application/json
> Content-Length: 60
>
< HTTP/1.1 201 Created
< Location: http:
//localhost:8080/posts/681a139012d5c00fcb674298

这不会返回实际的记录,但它会给我们一个指向它的Location头。这也可以直接在数据库中看到:


然后我们可以使用GET请求并指定 ID来检索该记录:

$ curl -v -u admin:secret localhost:8080/posts/681a139012d5c00fcb674298
> GET /posts/681a139012d5c00fcb674298 HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 152
<
{
  "_id": { "$oid": "681a139012d5c00fcb674298" },
 
"title": "Introduction to RESTHeart",
 
"author": "Baeldung",
 
"_etag": { "$oid": "681a139012d5c00fcb674297" }
}

我们还可以通过对整个集合使用GET请求来选择整个集合:

$ curl -v -u admin:secret localhost:8080/posts
> GET /posts HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 154
<
[
  {
    "_id": { "$oid": "681a139012d5c00fcb674298" },
   
"title": "Introduction to RESTHeart",
   
"author": "Baeldung",
   
"_etag": { "$oid": "681a139012d5c00fcb674297" }
  }
]

正如预期的那样,我们还可以使用PUT、 PATCH和DELETE调用来更新和删除这些记录:

$ curl -v -u admin:secret -X PUT localhost:8080/posts/681a139012d5c00fcb674298 -H "Content-Type: application/json" -d '{"title": "Intro to RESTHeart", "author": "Baeldung"}'
> PUT /posts/681a139012d5c00fcb674298 HTTP/1.1
> Content-Type: application/json
> Content-Length: 53
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 0
<

这些都不会返回结果,但如果我们再次查询,它会立即可用。

2. GraphQL API
除了 REST API 之外,RESTHeart 还允许我们通过 GraphQL API 公开数据。与 REST API 不同,这需要一些初始配置才能使一切正常工作。

所有 GraphQL API 都由gql-apps集合中的记录定义。因此,我们需要做的第一件事就是创建以下内容:

$ curl -v -u admin:secret -X PUT localhost:8080/gql-apps

然后,我们需要在此集合中创建一条包含 GraphQL API 定义的特殊记录。要创建一个公开我们一直在使用的 Posts 的 API,配置应如下所示:

$ cat posts.schema
{
    "_id": "restheart-posts",
   
"descriptor": {
       
"name": "restheart-posts",
       
"description": "RESTHeart Tutorial",
       
"enabled": true,
       
"uri": "restheart-posts"
    },
   
"schema": "type Post { title: String author: String } type Query { posts: [Post] }",
   
"mappings": {
       
"Post": {
           
"name": "name",
           
"author": "author"
        },
       
"Query": {
           
"posts": {
               
"db": "restheart",
               
"collection": "posts"
            }
        }
    }
}

descriptor字段提供了 RESTHeart 用于管理 API 的一些定义。这里最重要的部分是uri字段,我们稍后会用到它。
这里的schema字段是我们 API 的完整 GraphQL Schema 定义,以GraphQL Schema 定义语言编写。

mappings字段告诉 RESTHeart 如何在 GraphQL API 和 MongoDB 集合之间进行映射。

在本例中,我们定义了一个包含name和author字段的Post类型,以及一个包含posts字段的Query类型,该字段映射到我们数据库中的posts集合。

然后我们按照与之前相同的方式创建此记录:

$ curl -v -u admin:secret -X POST localhost:8080/gql-apps -d "@posts.schema" -H "Content-Type: application/json"

完成此操作后,我们的 GraphQL API 就可以使用了。我们将uri字段设置为restheart-posts,这意味着我们的 API 暴露在/graphql/restheart-posts上:

$ curl -v -u admin:secret -X POST localhost:8080/graphql/restheart-posts -d "{ posts { title author } }" -H "Content-Type: application/graphql"
> POST /graphql/restheart-posts HTTP/1.1
> Content-Type: application/graphql
> Content-Length: 26
>
* upload completely sent off: 26 bytes
< HTTP/1.1 200 OK
< Content-Type: application/graphql-response+json
< Content-Length: 83
<
{
 
"data": {
   
"posts": [
      {
       
"title": "Intro to RESTHeart",
       
"author": "Baeldung"
      }
    ]
  }
}

我们可以立即看到这是我们的 REST API 管理的相同数据。