正确处理可以同步或异步调用的REST API路径的方法

时间:2018-04-12 07:52:06

标签: java rest api asynchronous api-design

我正在开发一个处理文档的Spring Boot REST API,可以启动对文档的检查。

我有一个文档资源: <?php $name = $email = $subject = $message = ''; if ($_SERVER['REQUEST_METHOD'] == 'POST') { $name = test_input($_POST['username']); $email = test_input($_POST['email']); $linkedinurl = test_input($_POST['linkedin']); $message = test_input($_POST['message']); $jobrole = test_input($_POST['jobrole']); $captcha = test_input($_POST['g-recaptcha-response']); } function test_input($data) { $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data); return $data; } if(isset($_POST['file'])){ $cv_file = file_get_contents($_FILES['file']); } if (isset($_POST['g-recaptcha-response'])) { $captcha = $_POST['g-recaptcha-response']; } if (!$captcha) { echo 'Please check the captcha form.'; exit; } $secretKey = 'xxx'; $ip = $_SERVER['REMOTE_ADDR']; $response = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secretKey.'&response='.$captcha.'&remoteip='.$ip); $responseKeys = json_decode($response, true); if (intval($responseKeys['success']) !== 1) { echo '<h2>You are spammer !</h2>'; } else { echo ''; } $servername = 'xxx'; $username = 'xxx'; $password = 'xxx'; $dbname = 'xxx'; // Create connection $conn = new mysqli($servername, $username, $password, $dbname); // Check connection if ($conn->connect_error) { die('Connection failed: '.$conn->connect_error); } $sql = "INSERT INTO career_details (name, email, linkedin_url,job_role, message, cv) VALUES ('$name', '$email', '$linkedinurl', '$jobrole', '$message','$cv_file')"; if ($conn->query($sql) === true) { echo 'New record created successfully'; } else { echo 'Error: '.$sql.'<br>'.$conn->error; } $conn->close();

  1. 使用/doc
  2. 创建文档
  3. 使用POST /doc
  4. 的其余CRUD操作

    现在我可以启动对文档的检查,可以将检查视为操作或子资源。

    启动(创建)对文档的检查非常简单:/doc/{id}

    然而,检查可能需要一些时间,所以我想让用户选择启动同步或异步检查。

    我如何明智地处理这条道路?

    1. 用户是否应通过POST /doc/{id}/check上的查询参数选择同步或异步检查?
    2. 我应该创建2条不同的路径吗?
    3. 同样在异步检查的情况下,我会创建一个临时的Task资源,可以合并以了解支票的状态。

      但是如果检查和任务都从同一路径返回它会让人感到困惑,不是吗?

      我读了an article,其中说async中返回的资源应该是尽可能多地填充的检查资源,但是带有可以合并的任务的链接。

      这似乎是一种好方法;我会返回部分检查是否与指向与检查相关联的POST /doc/{id}/check的链接异步。

      但是我仍然对我的API应该提供什么路径感到困惑,让用户在同步和异步检查之间进行选择。

      你将如何处理它的路径和资源呢?

2 个答案:

答案 0 :(得分:2)

基本上它取决于你。通常,如果它是您要查询的大块数据,如String time = "15:00-18:05"; //Calculating OK //String time = "22:00-01:05"; //Not calculating properly String[] parts = time.split("-"); SimpleDateFormat format = new SimpleDateFormat("HH:mm"); Date date1 = null; Date date2 = null; Date dateMid = null; String dateInString = "24:00"; try { dateMid = format.parse(dateInString); } catch (ParseException e1) { e1.printStackTrace(); } try { date1 = format.parse(parts[0]); date2 = format.parse(parts[1]); } catch (ParseException e) { e.printStackTrace(); } long difference = date2.getTime() - date1.getTime(); if (date2.getTime()<date1.getTime()) //in case beyond midnight calculation { difference = dateMid.getTime()-difference; } int minutes = (int) ((difference / (1000*60)) % 60); int hours = (int) ((difference / (1000*60*60)) % 24); String tot = String.format("%02d:%02d", hours,minutes); System.out.println("dif2: "+tot); ,我使用的大多数API都使用GET进行同步请求,使用POST进行异步请求返回任务或作业ID。

对于你的情况下POST,如果创建/检查需要时间,我会考虑总是异步并返回HTTP 202 Accepted和doc / {id} / check / {id} url,用户可以看到结果,如果是准备好或某些状态仍然有效。

如果你想给他们一个等待或不等的选择,你可以选择如何去做。有一个标准头可用于修改行为。例如/resource/{id}用于异步调用而没有标头或Expect: 202-accepted用于同步调用。即使它是一个标准,这使得API不那么清晰。大多数人(包括我)可能会坚持在URL中添加一个参数以便澄清。我不认为它应该在POST数据中,因为它应该是与您正在创建的对象相关的数据

答案 1 :(得分:0)

这里有很多问题。我会尝试逐一回答

可以使用查询参数

来检查资源的运行状况
/doc/{id} - GET Get the resource details
/doc/{id}?healthCheck=true&async=true GET - Get the resource details and trigger an async health check

对于异步运行状况检查,您提到的响应将为202,并且响应包含指向运行状况URL的链接

HTTP/1.1 202 Accepted
Location: /doc/12345/status

如果客户端向此端点发送GET请求,则响应应包含请求的当前状态。可选地,它还可以包括估计的完成时间或取消操作的链接。

参考 https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design