设计 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 可能是有意义的:

  1. 您的目标资源是一辆汽车。所以它可以通过 URL "/auto"
  2. 函数"start"和"stop"用于改变资源的状态。所以这意味着你有一个 "sub-resource" 的 auto 可以通过 URL “/auto/state” 访问,可能的值,例如 "started","stopped"。这些值可以通过 GET 访问:/auto/state
  3. 现在可以使用 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.

一些可能有用的状态:

  • 200:使用该状态表示请求成功。
  • 202:使用此状态码表示请求已被接受处理,但处理尚未完成。
  • 204:使用此状态代码表示服务器已成功完成请求并且在响应负载正文中没有要发送的其他内容。
  • 409:使用这个表示由于与目标资源的当前状态冲突而无法完成请求。