我正在为客户管理系统编写RESTful服务,我正在尝试找到部分更新记录的最佳实践.例如,我希望调用者能够使用GET请求读取完整记录.但是为了更新它,只允许记录上的某些操作,比如将状态从ENABLED更改为DISABLED.(我有比这更复杂的场景)
出于安全原因,我不希望调用者仅使用更新的字段提交整个记录(这也感觉有点过分).
是否有推荐的构建URI的方法?在阅读REST书籍时,RPC样式调用似乎不受欢迎.
如果以下调用返回ID为123的客户的完整客户记录
GET /customer/123
<customer>
{lots of attributes}
<status>ENABLED</status>
{even more attributes}
</customer>
Run Code Online (Sandbox Code Playgroud)
我该如何更新状态?
POST /customer/123/status
<status>DISABLED</status>
POST /customer/123/changeStatus
DISABLED
...
Run Code Online (Sandbox Code Playgroud)
更新:增加问题.如何将"业务逻辑调用"纳入REST API?这是否有商定的方式?并非所有方法都是CRUD本质上.有些更复杂,比如' sendEmailToCustomer(123) ',' mergeCustomers(123,456) ',' countCustomers() '
POST /customer/123?cmd=sendEmail
POST /cmd/sendEmail?customerId=123
GET /customer/count
Run Code Online (Sandbox Code Playgroud)
谢谢弗兰克
我试图使用json
包将Go结构转换为JSON,但我得到的只是{}
.我确信这是完全明显的,但我没有看到它.
package main
import (
"fmt"
"encoding/json"
)
type User struct {
name string
}
func main() {
user := &User{name:"Frank"}
b, err := json.Marshal(user)
if err != nil {
fmt.Printf("Error: %s", err)
return;
}
fmt.Println(string(b))
}
Run Code Online (Sandbox Code Playgroud)
然后,当我尝试运行它时,我得到了这个:
$ 6g test.go && 6l -o test test.6 && ./test
{}
Run Code Online (Sandbox Code Playgroud) 我正在尝试构建一个Spring 3.1 PropertySource,它从Zookeeper节点读取它的值.为了连接到Zookeeper我正在使用Netflix的Curator.
为此,我构建了一个自定义属性源,它从Zookeeper读取属性的值并返回它.当我解析这样的属性时,这很好用
ZookeeperPropertySource zkPropertySource = new ZookeeperPropertySource(zkClient);
ctx.getEnvironment().getPropertySources().addLast(zkPropertySource);
ctx.getEnvironment().getProperty("foo"); // returns 'from zookeeper'
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试实例化一个带有@Value注释的字段的bean时,这会失败:
@Component
public class MyBean {
@Value("${foo}") public String foo;
}
MyBean b = ctx.getBean(MyBean.class); // fails with BeanCreationException
Run Code Online (Sandbox Code Playgroud)
这个问题很可能与Zookeeper没有任何关系,但是我正在注册属性源并创建bean.
任何见解都受到高度赞赏.
更新1:
我正在从这样的XML文件创建应用程序上下文:
public class Main {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
ctx.registerShutdownHook();
}
}
Run Code Online (Sandbox Code Playgroud)
连接到Zookeeper的类是@Component.
@Component
public class Server {
CuratorFramework zkClient;
public void connectToZookeeper() {
zkClient = ... (curator magic) ...
}
public …
Run Code Online (Sandbox Code Playgroud) Jackson 1.9.9在解析为标量值(布尔,整数,字符串)时有些不一致。任何数组或对象类型都会失败,但是您可以将任何标量类型放入字符串中。对于布尔值0和非0映射为false / true。int属性仅接受数字。
public class Foo { public String s; public boolean b; public int i; }
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.readValue("{\"s\":\"abc\"}", Foo.class).s); // "abc"
System.out.println(mapper.readValue("{\"s\":true}", Foo.class).s); // "true"
System.out.println(mapper.readValue("{\"s\":123}", Foo.class).s); // "123"
System.out.println(mapper.readValue("{\"b\":123}", Foo.class).b); // true
System.out.println(mapper.readValue("{\"b\":0}", Foo.class).b); // false
System.out.println(mapper.readValue("{\"b\":\"abc\"}", Foo.class).b); // fails with JsonMappingException
System.out.println(mapper.readValue("{\"i\":\"abc\"}", Foo.class).i); // fails with JsonMappingException
System.out.println(mapper.readValue("{\"i\":true}", Foo.class).i); // fails with JsonMappingException
System.out.println(mapper.readValue("{\"s\":[]}", Foo.class).s); // fails with JsonMappingException
System.out.println(mapper.readValue("{\"s\":{}}", Foo.class).s); // fails with JsonMappingException
System.out.println(mapper.readValue("{\"b\":[]}", Foo.class).b); // fails with JsonMappingException
System.out.println(mapper.readValue("{\"b\":{}}", …
Run Code Online (Sandbox Code Playgroud)