设计 API 以使用 Jersey 启动和停止进程
Designing API to start and stop a process with Jersey
我正在使用 Java 和 Jersey 开发 REST Web 服务器。这是我的第一个 Web 应用程序,我想确保我正在很好地构建应用程序。我创建了第一个运行良好的函数:
@Path("/startAuto")
public class Rest {
@GET
public String startAuto() {
try {
ProcessBuilder pb = new ProcessBuilder("/startAuto.sh");
Process p = pb.start();
p.waitFor();
return ("Auto Started");
} catch (Exception e) {
e.printStackTrace();
return ("error");
}
}
}
我想添加一个新功能,例如 stopAuto
。
哪个更干净:在此 class 中添加函数还是创建一个新的 class?
正如 peeskillet 在他的评论中指出的那样,这取决于您希望如何构建 URL
如果你想要
/auto/start 和
/auto/stop
我会全力以赴 class 结构如下
@Path("/auto")
public class Rest {
@GET
@Path("/start")
public String startAuto() {
}
@GET
@Path("/stop")
public String stopAuto() {
}
}
好的结构对于任何好的东西都是必不可少的project/product,但是这也是一个答案因情况而异的问题。
但是,如果有疑问,一个好的起点是按照“职责”对端点进行分组。如果它们属于一起,则将它们放在同一个 class 中。
个人意见:Boundary-Control-Entity 是我能找到的启动项目的最简单的起点。然后,该结构会根据需要进行调整。查看来自 Adam Bien 的 article 以获得更多想法。
一般把与当前资源相关的另一个函数放到同一个class.
但是您还应该记住,REST 操作的是资源而不是函数(名词而不是动词)。因此,让您的 API 更加 RESTfull 可能是有意义的:
- 您的目标资源是一辆汽车。所以它可以通过 URL "/auto"
- 函数"start"和"stop"用于改变资源的状态。所以这意味着你有一个 "sub-resource" 的 auto 可以通过 URL “/auto/state” 访问,可能的值,例如 "started","stopped"。这些值可以通过 GET 访问:/auto/state
- 现在可以使用 PUT/POST 请求以正文中的状态值更改 REST 样式的状态(也可以使用 PATCH 方法来部分更新自动)。在您的情况下,只保留一个方法作为端点公开是有意义的,该端点使用状态值和调用逻辑来根据参数启动或停止自动。
方法一
用GET
method should be used for retrieving information. Don't use GET
to change a state of a resource. Prefer POST
代替。
因此,您将得到如下内容:
- 启动进程:
POST /auto/start HTTP/1.1
Host: example.org
- 停止进程:
POST /auto/stop HTTP/1.1
Host: example.org
通过这种方法,您的资源中将包含以下内容 class:
@Path("/auto")
public class Rest {
@POST
@Path("/start")
public String start() {
...
}
@POST
@Path("/stop")
public String stop() {
...
}
}
方法二
REST 独立于协议并且是 resource-oriented architecture. When implementing REST applications over the HTTP protocol, for example, the resource is identified by the URI and the operation over the resource is expressed by the HTTP method.
使用这种方法,资源的新状态将在请求有效负载中使用 JSON 表示。要获取资源的状态,请使用 GET
and to replace the state of a resource, use PUT
.
你可以有以下内容:
- 启动进程:
PUT /auto/status HTTP/1.1
Host: example.org
Content-Type: application/json
{
"value" : "started"
}
- 停止进程:
PUT /auto/status HTTP/1.1
Host: example.org
Content-Type: application/json
{
"value" : "stopped"
}
- 获取进程状态:
GET /auto/status HTTP/1.1
Host: example.org
您的资源 class 将如下所示:
@Path("/auto/status")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class Rest {
@PUT
public String changeStatus(Status status) {
...
}
@GET
public Status getStatus() {
...
}
}
这就是 Status
class 的样子:
public class Status {
private String value;
// Default constructor, getters and setters omitted
}
响应状态代码
您当然需要将操作结果告知您的客户。为此,请使用 HTTP response status codes.
一些可能有用的状态:
我正在使用 Java 和 Jersey 开发 REST Web 服务器。这是我的第一个 Web 应用程序,我想确保我正在很好地构建应用程序。我创建了第一个运行良好的函数:
@Path("/startAuto")
public class Rest {
@GET
public String startAuto() {
try {
ProcessBuilder pb = new ProcessBuilder("/startAuto.sh");
Process p = pb.start();
p.waitFor();
return ("Auto Started");
} catch (Exception e) {
e.printStackTrace();
return ("error");
}
}
}
我想添加一个新功能,例如 stopAuto
。
哪个更干净:在此 class 中添加函数还是创建一个新的 class?
正如 peeskillet 在他的评论中指出的那样,这取决于您希望如何构建 URL
如果你想要
/auto/start 和
/auto/stop
我会全力以赴 class 结构如下
@Path("/auto")
public class Rest {
@GET
@Path("/start")
public String startAuto() {
}
@GET
@Path("/stop")
public String stopAuto() {
}
}
好的结构对于任何好的东西都是必不可少的project/product,但是这也是一个答案因情况而异的问题。 但是,如果有疑问,一个好的起点是按照“职责”对端点进行分组。如果它们属于一起,则将它们放在同一个 class 中。
个人意见:Boundary-Control-Entity 是我能找到的启动项目的最简单的起点。然后,该结构会根据需要进行调整。查看来自 Adam Bien 的 article 以获得更多想法。
一般把与当前资源相关的另一个函数放到同一个class.
但是您还应该记住,REST 操作的是资源而不是函数(名词而不是动词)。因此,让您的 API 更加 RESTfull 可能是有意义的:
- 您的目标资源是一辆汽车。所以它可以通过 URL "/auto"
- 函数"start"和"stop"用于改变资源的状态。所以这意味着你有一个 "sub-resource" 的 auto 可以通过 URL “/auto/state” 访问,可能的值,例如 "started","stopped"。这些值可以通过 GET 访问:/auto/state
- 现在可以使用 PUT/POST 请求以正文中的状态值更改 REST 样式的状态(也可以使用 PATCH 方法来部分更新自动)。在您的情况下,只保留一个方法作为端点公开是有意义的,该端点使用状态值和调用逻辑来根据参数启动或停止自动。
方法一
用GET
method should be used for retrieving information. Don't use GET
to change a state of a resource. Prefer POST
代替。
因此,您将得到如下内容:
- 启动进程:
POST /auto/start HTTP/1.1
Host: example.org
- 停止进程:
POST /auto/stop HTTP/1.1
Host: example.org
通过这种方法,您的资源中将包含以下内容 class:
@Path("/auto")
public class Rest {
@POST
@Path("/start")
public String start() {
...
}
@POST
@Path("/stop")
public String stop() {
...
}
}
方法二
REST 独立于协议并且是 resource-oriented architecture. When implementing REST applications over the HTTP protocol, for example, the resource is identified by the URI and the operation over the resource is expressed by the HTTP method.
使用这种方法,资源的新状态将在请求有效负载中使用 JSON 表示。要获取资源的状态,请使用 GET
and to replace the state of a resource, use PUT
.
你可以有以下内容:
- 启动进程:
PUT /auto/status HTTP/1.1
Host: example.org
Content-Type: application/json
{
"value" : "started"
}
- 停止进程:
PUT /auto/status HTTP/1.1
Host: example.org
Content-Type: application/json
{
"value" : "stopped"
}
- 获取进程状态:
GET /auto/status HTTP/1.1
Host: example.org
您的资源 class 将如下所示:
@Path("/auto/status")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class Rest {
@PUT
public String changeStatus(Status status) {
...
}
@GET
public Status getStatus() {
...
}
}
这就是 Status
class 的样子:
public class Status {
private String value;
// Default constructor, getters and setters omitted
}
响应状态代码
您当然需要将操作结果告知您的客户。为此,请使用 HTTP response status codes.
一些可能有用的状态: