设计API以使用Jersey启动和停止进程

时间:2016-04-13 13:32:07

标签: java 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

哪个更干净:在这个类中添加函数还是创建一个新类?

4 个答案:

答案 0 :(得分:3)

方法1

GET方法应该用于检索信息。不要使用GET来更改资源的状态。更喜欢POST

因此,您将拥有以下内容:

  • 启动流程:
POST /auto/start HTTP/1.1
Host: example.org
  • 停止流程:
POST /auto/stop HTTP/1.1
Host: example.org

使用此方法,您的资源类中将包含以下内容:

@Path("/auto")
public class Rest {

    @POST
    @Path("/start")
    public String start() {
        ...
    }

    @POST
    @Path("/stop")
    public String stop() {
        ...
    }
}

方法2

REST与协议无关,是resource-oriented架构。例如,通过HTTP协议实现REST应用程序时,资源由URI标识,资源上的操作由HTTP method表示。

通过这种方法,资源的新状态将使用JSON在请求有效负载中表示。要获取资源的状态,请使用GET并替换资源的状态,使用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

您的资源类将如下:

@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课程的样子:

public class Status {

    private String value;

    // Default constructor, getters and setters omitted
}

响应状态代码

您当然需要告知您的客户有关操作的结果。为此,请使用HTTP response status codes

一些可能有用的状态:

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

答案 1 :(得分:2)

正如peeskillet在评论中指出的那样,这取决于你想如何构建你的URL

如果你想要像

那样的话

/ auto / start和

/自动/停止

我会按照以下结构在一个类中进行所有操作

@Path("/auto") 
public class Rest {

    @GET
    @Path("/start")
    public String startAuto() {

    }

    @GET
    @Path("/stop")
    public String stopAuto() {

    }
}

答案 2 :(得分:0)

良好的结构对于任何好的项目/产品都是必不可少的,但它也是一个问题,其答案因情况而异。 但是,如果有疑问,一个好的起点是根据“职责”对您的终端进行分组。如果它们属于一起,则将它们放在同一个类中。

个人意见:Boundary-Control-Entity是我找到的最简单的起点,可用于启动项目。然后结构根据需要进行调整。看看Adam Bien的这个article以获得更多想法。

答案 3 :(得分:0)

通常最好将与当前资源相关的另一个函数放入同一个类中。

但是你还应该记住,REST使用资源但不使用函数(名词而不是动词)。因此,使API更加RESTfull可能是有意义的:

  1. 您定位资源这是一个自动。因此可以通过URL“/ auto”
  2. 访问它
  3. 函数“start”和“stop”用于更改资源的状态。因此,这意味着您拥有可以通过URL“/ auto / state”访问的auto的“子资源”,其中包含可能的值,例如“已启动”,“已停止”。 GET可以访问此值:/ auto / state
  4. 现在可以使用带有状态值的PUT / POST请求以REST样式更改状态(也可以使用PATCH方法以部分更新auto)。也许,在您的情况下,将一个方法暴露为端点消耗状态值并调用逻辑以根据参数启动或停止自动是有意义的。