我的老板让我在我们的某些产品上实施RESTful网络服务。我们是一家初创公司,我是唯一一位分配给这项任务的人。
我对Web服务一无所知,也没有提及RESTful Web服务。
所以我想开始。
因为我无法说出我们提供的服务,所以我可以假设以下产品:
用户只需键入一个参数为x和y的url,我的服务就会返回x * y的结果。我认为这是一个非常基本的RESTful Web服务,对吧?请忽略有多少用户将访问它的详细信息。我可以假设很多用户都会有我们的服务。
我该如何开始,我需要学习什么?
我应该在服务器端设置Tomcat + RESTful主机软件吗?
请给我一些指导和提示。
由于
我认为Google Reader API / Facebook API / Twitter API是我要实现的RESTful服务的一个很好的例子。谷歌和其他公司是如何实现这一目标的?
答案 0 :(得分:4)
您没有指定语言,这使得它很难,但有许多框架可以帮助您制作RESTful服务。
对于java来说,一个不错的是Jersey(http://jersey.java.net/),因为你提到了Tomcat,我假设你将使用Java。
通过遵循教程,您将构建简单的服务,然后您可以开始添加更多的复杂性。
您可能需要阅读此内容:
http://ajaxpatterns.org/RESTful_Service
了解REST
。
例如,何时使用GET,POST或PUT,以及在出现各种错误时应使用哪些响应代码。
答案 1 :(得分:1)
好消息:只要你宣称它是什么,你所做的一切都将是RESTful。 坏消息:你有点自己定义服务,因为没有“标准”的方式来做RESTful服务。从第1项开始。
如果您的网络服务真的就像多重操作一样简单,那么它就是一个生活在网址中的网页yourcompany.com/service/multiply,它可以带有2个参数,也许是旧的 - 塑造GET方式(获取yourcompany.com/service/multiply?x=7&y=6)或作为两个POST参数,然后生成一个只包含一个字符串“42”的响应。 现在,随着您的请求变得更加复杂,您可以将它们格式化为简单的XML:
<multiply>
<arg value="6">
<arg value="7">
</multiply>
和回复
<response value="42"/>
或者你想要什么。或者也许是JSON。您还需要确保为每个方法调用指定应使用哪种HTTP方法,并确保它们有意义(例如,PUT用于上载,DELETE用于删除)。 你明白了。 RESTful不是规范,而是思考Web服务的方式。
答案 2 :(得分:0)
我首先要了解什么是RESTful服务,因为当您不了解需求时,平台将无济于事。
您可以从阅读本文开始:http://www.ibm.com/developerworks/webservices/library/ws-restful/ 然后使用您决定实施服务的编程语言进行谷歌RESTful服务
答案 3 :(得分:0)
WCF REST的简单示例。
[ServiceContract]
public interface IService1
{
[WebGet(UriTemplate = "contact/{PID}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
Person GetContact(string PID);
//[WebInvoke(Method = "POST", UriTemplate = "person")]
[OperationContract]
[WebInvoke(UriTemplate = "/create", Method = "POST")]
void SaveContact(Person person);
[WebGet(UriTemplate = "/")]//RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)
[OperationContract]
List<Person> GetAllContacts();
[OperationContract]
[WebInvoke(UriTemplate = "/{id}", Method = "PUT")]
void UpdateProduct(string id, Person person);
[OperationContract]
[WebInvoke(UriTemplate = "/{id}", Method = "DELETE")]
void DeleteProduct(string id);
[OperationContract]
[WebInvoke(UriTemplate = "UploadFile")]
void UploadFile(Stream stream);
}
// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract(Namespace = "")]
public class Person
{
[DataMember]
public string PersonId { get; set; }
[DataMember]
public string PersonName { get; set; }
}
Service Implementation :
public class Service1 : IService1
{
public Person GetContact(string PID)
{
return new Person(){PersonId=PID, PersonName=PID+".Name"};
}
public void SaveContact(Person person)
{
int a = 0;
}
public void UpdateProduct(string id, Person person)
{
int b = 0;
}
public List<Person> GetAllContacts()
{
List<Person> lstPerson = new List<Person>();
for (int i = 0; i < 10; i++)
{
Person p = new Person();
p.PersonId = i.ToString();
p.PersonName = i + "Person";
lstPerson.Add(p);
}
return lstPerson;
}
public void DeleteProduct(string id)
{
int c = 0;
}
public void UploadFile( System.IO.Stream stream)
{
object obj = stream;
}
}
Call Rest service using WebRequest :
class Program
{
static void Main(string[] args)
{
new Program().GetContacts();
//new Program().AddContacts();
//new Program().Update();
//new Program().Delete();
}
public void GetContacts()
{
WebRequest req = WebRequest.Create(@"http://localhost:60517/Service1.svc/");
req.Method = "GET";
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
if (resp.StatusCode == HttpStatusCode.OK)
{
using (Stream respStream = resp.GetResponseStream())
{
StreamReader reader = new StreamReader(respStream, Encoding.UTF8);
Console.WriteLine(reader.ReadToEnd());
}
}
else
{
Console.WriteLine(string.Format("Status Code: {0}, Status Description: {1}", resp.StatusCode, resp.StatusDescription));
}
Console.Read();
}
public void AddContacts()
{
WebRequest req = WebRequest.Create(@"http://localhost:60517/Service1.svc/create");
req.Method = "POST";
req.ContentType = @"application/xml; charset=utf-8";
WriteProductXml(req, "11", "Asif");
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
Console.WriteLine(string.Format("Status Code: {0}, Status Description: {1}", resp.StatusCode, resp.StatusDescription));
Console.Read();
}
public static void WriteProductXml(WebRequest req, string name, string description)
{
StringBuilder builder = new StringBuilder();
builder.AppendLine("<Person>");
builder.AppendLine("<PersonId>" + description + "</PersonId>");
builder.AppendLine("<PersonName>" + name + "</PersonName>");
builder.AppendLine("</Person>");
req.ContentLength = Encoding.UTF8.GetByteCount(builder.ToString());
using (Stream stream = req.GetRequestStream())
{
stream.Write(Encoding.UTF8.GetBytes(builder.ToString()), 0, Encoding.UTF8.GetByteCount(builder.ToString()));
}
}
public void Update()
{
WebRequest req = WebRequest.Create(@"http://localhost:60517/Service1.svc/1");
req.Method = "PUT";
req.ContentType = @"application/xml; charset=utf-8";
WriteProductXmlUpdate(req, "11", "Asif");
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
Console.WriteLine(string.Format("Status Code: {0}, Status Description: {1}", resp.StatusCode, resp.StatusDescription));
Console.Read();
}
public static void WriteProductXmlUpdate(WebRequest req, string name, string description)
{
StringBuilder builder = new StringBuilder();
builder.AppendLine("<Person>");
builder.AppendLine("<PersonId>" + description + "</PersonId>");
builder.AppendLine("<PersonName>" + name + "</PersonName>");
builder.AppendLine("</Person>");
req.ContentLength = Encoding.UTF8.GetByteCount(builder.ToString());
using (Stream stream = req.GetRequestStream())
{
stream.Write(Encoding.UTF8.GetBytes(builder.ToString()), 0, Encoding.UTF8.GetByteCount(builder.ToString()));
}
}
public void Delete()
{
WebRequest req = WebRequest.Create(@"http://localhost:60517/Service1.svc/1");
req.Method = "DELETE";
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
Console.WriteLine(string.Format("Status Code: {0}, Status Description: {1}", resp.StatusCode, resp.StatusDescription));
Console.Read();
}
}