REST API: Java Spring Boot and MongoDB

第一次做翻译的如果有没翻译准确的欢迎指出,Typora上面编辑的文章移植到CSDN格式就有很多问题,如有需要可以到我的CSDN下载中下载()或者直接邮箱艾特我本人。

作者是:Thomas Gleason

REST API: Java Spring Boot and MongoDB

REST API:Java Spring Boot 和 MongoDB

Creating a RESTful web service using the Spring Boot framework and MongoDB

 

创建一个rest风格的web 服务项目,使用springboot 框架和mongodb技术。

 

Why Spring Boot?

为什么选择spring boot呢?

The Java Spring Boot framework provides a powerful set of tools for web development on both the front-end and back-end. It has built-in configuration for security and database access, as well as simple request mappings. This framework is highly configurable and makes web development extremely simple.

Java spring boot 框架为web开发的前后端提供了一个强大的工具集。它含有内置的为了安全和数据库访问的配置,以及简单的请求映射。这个框架是高度可配置的并且使web开发变的极其简单。

Why MongoDB?

为什么选择MongoDB呢?

Mongo is quickly growing in popularity among NoSQL databases. Read more about NoSQL and its benefits here. MongoDB, specifically, is perfect for developing a REST API with Spring Boot for a couple of key reasons:

  • Data is stored in MongoDB as JSON
  • Spring Boot provides a powerful MongoDB connector

Mongo 在受欢迎的非关系型数据库中迅速增长。在这可以读到更多关于非关系型数据库以及它们的优势。MongoDb 具体来说,由于以下两个关键的原因是非常适合集成springboot来开发一个rest风格的API:

数据存储在MongoDB中的格式是JSON的

Spring Boot 提供了一个强大的MongoDB 连接器

Tools Used in this Tutorial

本教程中使用的工具如下所示

  1. Java
  2. Spring Boot
  3. Maven
  4. MongoDB
  5. Postman

Step 1: Creating a Database

第一步:创建一个数据库

This tutorial assumes that you already have an accessible instance of MongoDB that you can connect to. For more information on getting started with MongoDB, visit their online tutorial.

Let us start by creating a test database. I will call mine “rest_tutorial” using the following command in the MongoDB shell, or through a database manager like MongoDB Compass:

本教程是假定你已经有了一个可以访问并且可以连接的MongoDB的实例。想了解更多的MongoDB的入门信息可以访问他们的在线教程。

让我们开始创建一个测试的数据库。我将会调用我自己的"rest_tutorial",通过使用如下的在MongoDB的shell中的命令,或者通过一个数据库的管理工具类似于"MongoDB Compass":

use rest_tutorial;
db.createCollection(“pets”);
db.createCollection(“pets”);
{
  “name” : “Spot”,
  “species” : “dog”,
  “breed” : “pitbull”
}
db.pets.insertMany([
  {
    “name” : “Spot”,
    “species” : “dog”,
    “breed” : “pitbull”
  },
  {
    “name” : “Daisy”,
    “species” : “cat”,
    “breed” : “calico”
  },
  {
    “name” : “Bella”,
    “species” : “dog”,
    “breed” : “australian shepard”
  }
]);

使用 db.pets.find({}); 查询这个集合时,MongoDB会为每个文档自动创建一个唯一的unique_id字段,用来使查找和编辑文档更加方便。

Querying the collection with db.pets.find({}); reveals that MongoDB automatically assigns a unique _id field to each document to make it easier to find and edit documents.

 

我们使用如下命令为这个集合添加数据:

We can add data to the collection with the following command:

一旦这个集合被创建了,我们需要我们需要添加一些数据!这个集合将会包含各种宠物的名字,品种,和种类。因此单文档格式如下所示:

Once the collection is created, we need to add some data! This collection will hold the names, breeds, and species of various pets, so a single document would be formatted as follows:

在MongoDB中,集合类似于在关系型数据库中的表-他们持有数据而我们将会使用我们的REST API去查询数据。我将会创建一个简单的集合,包含不同类型的宠物的数据。使用如下命令去创建这个集合。

In MongoDB, collections are analogous to tables in a relational database — they hold the data that we will be querying using our REST API. I will be creating a sample collection that will hold data about different types of pets. Let’s create the collection with the following command:

第二步:添加一个MongoDB的集合和数据

Step 2: Adding a MongoDB Collection and Data

使用上面这个命令将会在MongoDB中创建一个新的数据库,我们可以用于我们的教程。

This will create a new database in MongoDB that we can use for our tutorial.

Using Spring Initializr to Create a Project

使用Spring Initializr去创建一个项目

Spring offers a tool called the Spring Initializr to help jump-start your Spring Boot project. Access the Initializr at start.spring.io, and enter the following information:

  • Group: This is the package name Example: com.example.gtommee
  • Artifact: This is the project name Example: rest_tutorial
  • Dependencies: These are the features that will be added to your project (remember, you can always add these later) Our tutorial will use the “Web” and “MongoDB” dependencies

Spring提供了一个工具叫做Spring Initializr,来帮助你的Spring Boot 项目快速启动。进入Initializr官网,它网址是 start.spring.io,输入如下信息:

Group:包名字

填写示例:com.example.gtommee

Artifact:项目名字

填写示例:rest_tutorial

Dependencies:这些内容将会被添加到你的项目中去(请记住,你可以要晚一点再添加上它们)

我们的教程将会使用这个"Web"和“MongoDB” 的依赖

Then click Generate Project to download a .zip file with the basic project structure.

然后点击Generate Project 去下载基础项目结构的a.zip压缩包文件

 

Adding Model to Spring Boot Project

为这个SpringBoot项目添加模型

With the project downloaded from the Spring Initializr, you can now open it in your favorite IDE to begin editing the project. First, we will want to add a pets model, so that Spring will know what kind of data the database will return. We can do this by creating a new folder in src/main/java/[package name]/ called “models”. In the new “models” folder, we can create a file called Pets.java. This Java class will hold the basic structure of a document in the “pets” collection, so the class looks as follows

 

从Spring Initializr官网下载了这个项目后,你可以用你最喜欢的IDE工具打开它,开始编辑这个项目。首先我们想要添加一个宠物的模型,这样以来Spring就会知道数据库将会返回哪种类型的数据。我们为了实现它可以在 src/main/java/[package name]/ 下边创建一个新的文件夹叫做"models"。在这个新的"models"的文件夹中,我们可以创建一个文件名字叫做Pets.java。这个Java类将会包含一个在宠物集合中的基础结构文档。因此这个类看起开如下所示:

package com.example.gtommee.rest_tutorial.models;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
public class Pets {
  @Id
  public ObjectId _id;
 
  public String name;
  public String species;
  public String breed;
 
  // Constructors
  public Pets() {}
 
  public Pets(ObjectId _id, String name, String species, String breed) {
    this._id = _id;
    this.name = name;
    this.species = species;
    this.breed = breed;
  }
 
  // ObjectId needs to be converted to string
  public String get_id() { return _id.toHexString(); }
  public void set_id(ObjectId _id) { this._id = _id; }
 
  public String getName() { return name; }
  public void setName(String name) { this.name = name; }
 
  public String getSpecies() { return species; }
  public void setSpecies(String species) { this.species = species; }
 
  public String getBreed() { return breed; }
  public void setBreed(String breed) { this.breed = breed; }
}

文中的@Id注解告诉Spring这个_id字段将会被作为主标识符所使用。类的其他部分包含了这个Pets(宠物)对象的基本构造函数,getters方法,setters方法。

The @Id annotation tells spring that the _id field will be used as the primary identifier. The rest of the class contains the basic constructors, getters, and setters for the Pets object.

Adding Repository to Spring Boot Project

为SpringBoot项目添加仓库

Now that we have a model that identifies the data structure stored in the database to Spring Boot, we can create the connector between the model and MongoDB. This is done through a Repository interface. We can create this first by making a new folder called “repositories” in src/main/java/[package name]/.

现在,在SpringBoot中,我们有一个模型去标识的数据库中数据存储结构。我们可以创建一个连接器在模型和MongoDB。通过一个仓库的接口来实现。我们可以创建这个,通过在src/main/java/[package name]/`目录下创建一个新的文件夹,名字是repositories。

In the new “repositories” folder, we can create a file called PetsRepository.java. The name of this repository is extremely important because it tells MongoDB the collection that it will be querying (in this case, the pets collection). This interface will extend the MongoRepository class, which already contains generic methods like save (for creating/updating documents) and delete (for removing documents), but we will need to specify additional methods ourselves.

在新的名字是“repositories” 的文件夹下,我们可以创建一个名字叫PetsRepository.java的文件。这个repository的名字是极其重要的,因为它会告诉MongoDB,哪个集合将会被执行(在这个例子中,宠物就是这个集合)。这个接口会继承MongoRepository类,并且这个类中已经包含了基础方法比如说存储(用于创建或者新增文件)以及删除(用于移除文件),但是我们将需要我们自己指定的额外的方法。

Luckily, we do not need to manually implement these queries, we can simply use Spring Boot’s repository naming conventions, and the MongoRepository will intelligently construct the queries at runtime. This means that our interface will be extremely simple, as follows:

幸运的是我们不需要手动实现这些查询方法,我们可以很简单的去使用SpringBoot 框架中叫做约定的仓储 ,

MongoRepository将会在运行时智能的构造该查询方法。这就意味着我们的接口将会变得极其简单,如下所示:

package com.example.gtommee.rest_tutorial.repositories;
import com.example.gtommee.rest_tutorial.models.Pets;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface PetsRepository extends MongoRepository<Pets, String> {
  Pets findBy_id(ObjectId _id);
}

Adding the MongoDB Connection Info

To tell Spring the connection information for our MongoDB, we will need to add conection details to the application.properties file, located in the “src/main/resources” folder. Add the following lines to the file, replacing the information in brackets with the information specific to your MongoDB instance:

 

我们需要为application.properties 文件添加连接细节,这样以来就可以告知Spring框架去连接MongoDB的信息,这个application.properties 文件位于“src/main/resources” 目录下的文件夹内。添加下列行到该文件中去。并且用你的MongoDB实例的具体信息去替代括号中的信息。

spring.data.mongodb.host=[host]
spring.data.mongodb.port=[port]
spring.data.mongodb.authentication-database=[authentication_database]
spring.data.mongodb.username=[username]
spring.data.mongodb.password=[password]
spring.data.mongodb.database=rest_tutorial

这就是Spring连接数据库的所有信息

This is all the information that Spring will need to connect to the database.

Creating REST Controller

创建rest风格的Controller

Spring should now be able to connect to MongoDB, so now we can establish the enpoints that we can contact to interact with the database. This will be done in a Spring Rest Controller, which uses Request Mappings to map requests with functions. We can create a Rest Controller by adding a file called PetsController.java to the src/main/java/[package name]/ folder. The basic file structure will look as follows:

现在Spring应该可以连接到MongoDB了,那么现在我们可以建立同数据库直接相互联系的端点了。这个将会在Spring中的Rest风格的Controller类中实现它。通过使用请求映射将请求映射到方法中。通过在src/main/java/[package name]/文件夹下添加一个名字为PetsController.java的类,这样我们就可以创建一个Rest风格的controller。这个基本的文件结构看起来就像如下展示:

package com.example.gtommee.rest_tutorial;
import com.example.gtommee.rest_tutorial.models.Pets;
import com.example.gtommee.rest_tutorial.repositories.PetsRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping(“/pets”)
public class PetsController {
  @Autowired
  private PetsRepository repository;
}

这个@RestController 注解会告诉Spring 这个类将会被URL所请求,并且将会返回数据给请求者。这个@RestController 注解的作用是指定了会被处理的基本的URL,任何以“/pets” 开头的主机的请求将会被指定到此Controller(控制器)。

The @RestController annotation tells Spring that this class will requested by URL and will return data to the requester. The @RequestMapping annotation specifies the base URL that the controller will be handling, so any request to the host starting with “/pets” will be directed to this controller. The @Autowired annotation creates an instance of the PetsRepository object that will allow us to access and modify the pets database.

这个@RestController 注解会告诉Spring 这个类将会被URL所请求,并且将会返回数据给请求者。这个@RestController 注解的作用是指定了会被处理的基本的URL,任何以“/pets” 开头的主机的请求将会被指定到此Controller(控制器)。这个@Autowired 注解创建了一个PetsRepository对象是实例,使用这个对象将会允许我们访问和修改这个pets的数据。

Adding the REST Endpoints

添加rest风格的终端

All of the following enpoints will be added directly into the PetsController class.

以下所有的端点将会被直接添加到PetsController类中去。

GET

get

@RequestMapping(value = “/”, method = RequestMethod.GET)
public List<Pets> getAllPets() {
  return repository.findAll();
}
@RequestMapping(value = “/{id}”, method = RequestMethod.GET)
public Pets getPetById(@PathVariable(“id”) ObjectId id) {
  return repository.findBy_id(id);
}

The first mapping takes any GET requests to the host with a URL of /pets/and maps them to the getAllPets() method, which requests all documents from the pets collection.

第一个映射是表示任何在URL中含有/pets/字样的get请求都可以去访问主机,并且映射他们到这个getAllPets() 方法找那个去,可以请求pets集合中所有文件。

 

The second mapping takes and GET requests to the host with a URL of /pets/ followed by an ObjectId and maps them to the getPetById()method, which searches the pets collection for the document with an _idfield equal to the ObjectId in the URL.

第二个映射表示任何在URL中含有/pets/字样,并且后边是对象的ID的get请求都可以访问该主机,并且映射到getPetById()方法中去,查找到/pets/集合文档中的_id字段与URL中对象ID相等的内容。

PUT

@RequestMapping(value = “/{id}”, method = RequestMethod.PUT)
public void modifyPetById(@PathVariable(“id”) ObjectId id, @Valid @RequestBody Pets pets) {
  pets.set_id(id);
  repository.save(pets);
}

这个映射期待一个请求体(Json格式的),每个字段都是Pets对象所包含的(名字,特征,和品种)。这个ID在请求的url中对应的是文档中将要被修改的_id字段。

This mapping expects a request body (in JSON format) with each of the fields that a Pets object contains (name, species, and breed). The id in the request URL is the _id of the document to be modified.

POST

@RequestMapping(value = “/”, method = RequestMethod.POST)
public Pets createPet(@Valid @RequestBody Pets pets) {
  pets.set_id(ObjectId.get());
  repository.save(pets);
  return pets;
}

这个映射期待一个请求体(Json 格式的),里面的每一个字段都是Pets实体对象中所包含的(名字,特征,和品种),并且给他分配一个新的对象ID。这个对象之后会被插入到这个pets集合中去,兵器新的Pets对象将会被返回给请求者。

This mapping expects a request body (in JSON format) with each of the fields that a Pets object contains (name, species, and breed), and assigns it a new ObjectId. This object is then inserted into the pets collection, and the new Pets object is returned.

这个映射期待一个请求体(Json 格式的),里面的每一个字段都是Pets实体对象中所包含的(名字,特征,和品种),并且给他分配一个新的对象ID。这个对象之后会被插入到这个pets集合中去,兵器新的Pets对象将会被返回给请求者。

DELETE

@RequestMapping(value = “/{id}”, method = RequestMethod.DELETE)
public void deletePet(@PathVariable ObjectId id) {
  repository.delete(repository.findBy_id(id));
}

这个端点携带了pets集合的文档中的_id字段,并且可以从集合中删除该文档。

This endpoint takes the _id of a document in the pets collection and removes that document from the collection.

Completed Controller

package com.example.gtommee.rest_tutorial;
import com.example.gtommee.rest_tutorial.models.Pets;
import com.example.gtommee.rest_tutorial.repositories.PetsRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;@RestController
@RequestMapping(“/pets”)
public class PetsController {
  @Autowired
  private PetsRepository repository;
 
  @RequestMapping(value = “/”, method = RequestMethod.GET)
  public List<Pets> getAllPets() {
    return repository.findAll();
  }  @RequestMapping(value = “/{id}”, method = RequestMethod.GET)
  public Pets getPetById(@PathVariable(“id”) ObjectId id) {
    return repository.findBy_id(id);
  }
 
  @RequestMapping(value = “/{id}”, method = RequestMethod.PUT)
  public void modifyPetById(@PathVariable(“id”) ObjectId id, @Valid @RequestBody Pets pets) {
    pets.set_id(id);
    repository.save(pets);
  }
 
  @RequestMapping(value = “/”, method = RequestMethod.POST)
  public Pets createPet(@Valid @RequestBody Pets pets) {
    pets.set_id(ObjectId.get());
    repository.save(pets);
    return pets;
  }
 
  @RequestMapping(value = “/{id}”, method = RequestMethod.DELETE)
  public void deletePet(@PathVariable ObjectId id) {
    repository.delete(repository.findBy_id(id));
  }
}

Now that the controller has all of our endpoints, we can begin testing our API! From the command line, in the project root, run the mvn spring-boot:run command to compile the code and start the Spring server with the default port 8080.

测试你的API( 应用程序接口)

Testing Your API

测试你的API( 应用程序接口)

Now that the controller has all of our endpoints, we can begin testing our API! From the command line, in the project root, run the mvn spring-boot:run command to compile the code and start the Spring server with the default port 8080.

现在这个控制器含有我们所有的端点,我们可以开始去测试我们的接口了。从命令行进入如项目的根目录,运行

mvn spring-boot:run命令,去变异这些代码,并且用默认端口号8080去启动Spring的服务器。

Once the server starts, you are free to test your API however you choose.

POST 'http://localhost:8080/pets'

 

用post方式访问URL为 `'http://localhost:8080/pets'的地址且

With body : {“name” : “Liam”, “species” : “cat”, “breed” : “tabby”}

请求体是: `{“name” : “Liam”, “species” : “cat”, “breed” : “tabby”}

and header : Content-Type: application/json

请求头是json格式的

Returns:

返回值是

{
  “_id”: “5aecef5b6d55754834124df3”,
  “name”: “Liam”,
  “species”: “cat”,
  “breed”: “tabby”
}

PUT ‘http://localhost:8080/pets/5aecef5b6d55754834124df3

用put方式访问URL为‘http://localhost:8080/pets/5aecef5b6d55754834124df3`的地址且

With body : {“name” : “Liam”, “species” : “cat”, “breed” : “siamese”}

请求体是:{“name” : “Liam”, “species” : “cat”, “breed” : “siamese”}

and header : Content-Type : application/json

请求头是json格式的

Returns:

返回值是

empty response

空的响应体

GET ‘http://localhost:8080/pets/5aecef5b6d55754834124df3’

用GET方式访问URL是‘http://localhost:8080/pets/5aecef5b6d55754834124df3’的地址

Returns:

返回值是:

{
  “_id”: “5aecef5b6d55754834124df3”,
  “name”: “Liam”,
  “species”: “cat”,
  “breed”: “siamese”
}

DELETE ‘http://localhost:8080/pets/5aecef5b6d55754834124df3’

用delete方法访问地址为 ‘http://localhost:8080/pets/5aecef5b6d55754834124df3’的URL

Returns:

返回值是:

empty response

返回值是:

Returns:

用get方法访问地址是‘http://localhost:8080/pets’的URL

GET ‘http://localhost:8080/pets’

返回值是:

[
  {
    “_id”: “5aeccb0a18365ba07414356c”,
    “name”: “Spot”,
    “species”: “dog”,
    “breed”: “pitbull”
  },
  {
    “_id”: “5aeccb0a18365ba07414356d”,
    “name”: “Daisy”,
    “species”: “cat”,
    “breed”: “calico”
  },
  {
    “_id”: “5aeccb0a18365ba07414356e”,
    “name”: “Bella”,
    “species”: “dog”,
    “breed”: “australian shepard”
  }
]

Future Articles

未来的文章

Now you have created a REST API using Java Spring Boot and MongoDB! In future articles, I will explain how to add additional features to your API, such as authentication! I will list the articles here as they become availible.

现在你创建了一个使用Java SpringBoot 框架和MongoDB数据库的rest风格的应用程序接口!在为了的文章里面我将会解释如何在你的应用程序接口中去添加其他的功能。例如权限验证!我将会在这列出这些文章,使他们变的可用。