Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should web service be separate from web site? [closed]

Tags:

I am building a website and also want to build a REST web service for accessing a lot of the same functionality (using google app engine and spring mvc3), and I'm not sure of the best practices for how integrated/separate the 2 parts should be.

For example if I want view a resource I can provide a url in the form:

{resourcetype}\{resourceid} 

A GET request to this url can be redirected at a view which generates a webpage when the client is HTML/browser based. Spring has (from what I read - not tried it yet) the ability to use this same resource URL to serve up a view which returns HTML/Xml/JSON depending on the content type. This all seems great.

POST requests to a URL to create new resources in REST should return 201 CREATED (or so I read) along with the URL of the created resource, which seems fine for the Api but seems a little different from what would be expected from the norm in a web page (where you would likely be redirected to a page showing the resource you created or to a page saying it was created successfully or similar). Should I handle this by serving up a page at a different URL which contains the form for creating the resource, then submits to the Api URL via ajax and gets the response and redirects to the resource URL included in the response.

This pattern seems like it would work (and should work for DELETE too) but is this a good approach or am I better keeping the REST Api URLs and the web site URLs separate? this seems like it could introduce a fair bit of duplication and extra work. But having a single URL could mean that you are dependent on javascript being available on the client of a HTML 5 supporting browser.

like image 512
Sam Holder Avatar asked Nov 16 '11 19:11

Sam Holder


People also ask

What is the difference between REST API and web services?

Web service is used for REST, SOAP and XML-RPC for communication while API is used for any style of communication. Web service supports only HTTP protocol whereas API supports HTTP/HTTPS protocol. Web service supports XML while API supports XML and JSON.

Is Web API and Web service are same?

Though APIs and web services can both facilitate data transfers between applications over the internet, they are not the same, and the terms should not be used interchangeably in every case. The key distinction is that web services are a type of API: All web services are APIs, but not all APIs are web services.

Is REST API a Web service?

Overview. A REST API (also known as RESTful API) is an application programming interface (API or web API) that conforms to the constraints of REST architectural style and allows for interaction with RESTful web services. REST stands for representational state transfer and was created by computer scientist Roy Fielding.

Does every website have an API?

Not every site has (or wants) to invest the developer time in creating APIs. Smaller ecommerce sites, for example, may skip creating APIs for their own sites, especially if they also sell through Amazon (who already has their own API).


2 Answers

I suggest you keep them separate. By doing this you gain several benefits.

First, you decouple your web urls from you API urls so they can each change independently. For example, you may need to release backwards incompatible change to your API, in which case you can create a /v2/ directory. Meanwhile, you might want an /about page on the website but don't need one for your API.

By using different URLs, you simplify your implementation. Now every method doesn't have to determine if it's fronting JSON/XML or HTML. This is true even if you have a framework like Spring doing the heavy lifting; you still have do extra things for the website with respect to the current user.

It also eliminates a whole class of bugs. For example, users won't get JSON or XML output back while browsing the site—even if they have custom browser anonymity settings.

You can easily separate the logic for authentication. With a website, you need a login page and cookies. With an API, these aren't required but extra authentication headers are (for example, an HMAC+sha256 signature).

Finally, by separating the site from the API, you allow for different scaling needs. If your API is getting hit hard but not the website, you can throw more hardware at the API while keeping the minimal needed for the website.


Update: To clarify, I'm not suggesting you code up everything twice. There are two different ways to look at this to remove duplication.

First, in MVC parlance, you have one model and two different views on that model. This is the whole point of MVC so that the view and model are not tied together. The code to get a particular resource is the same in both clients, so it you could write your model such that only one line of code gets that resource from the database or wherever it comes from. In short, your model is an easy-to-use library with two clients.

Another way to look at it is that your website is your very first client of your public REST API; the web server actually calls your RESTful API to gets it's information. This is the whole Eat Your Own Dog Food principle.

like image 72
Michael Deardeuff Avatar answered Nov 09 '22 22:11

Michael Deardeuff


I disagree with Michael's answer and use it as a basis for my own:

To "decouple your web urls from you API urls so they can each change indepentently." is to spit in the face of REST. Cool URIs don't change. Don't concern yourself with changing your URLs. Don't version your API using URIs. REST uses links to espouse the OCP - a client operating on the previous version of your API should happily follow the links that existed when it went live, unknowing of new links that you've added to enhance your API.

If you insist on versioning your API, I'd ask that you do so using the media type, not the URI.

Next, " you simplify your implementation. Now every method doesn't have to determine if it's fronting JSON/XML or HTML."

If you're doing it this way, you're doing it wrong. Coming from Jersey, I return the same damn object from every method whether or not I produce HTML, XML or JSON. That's a completely cross-cutting concern that a marshaller takes care of. I use a VelocityMessageBodyWriter to emit HTML templates surrounding my REST representations.

Every resource in my system follows the same basic behavior:

class FooResource extends Resource {     @GET     public FooRepresentation get() {         return new FooRepresentation();     }     @POST     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)     public Response postForm(MulivaluedMap<String, String> form) {         return post(buildRepresentationFromForm(form));     }     @POST     @Consumes(MediaType.APPLICATION_XML)     public Resopnse post(FooRepresentation representation) {          // return ok, see other, whatever     } } 

The GET method may need to build Links to other resources. These are used by consumers of a REST API as well as the HTML template. A form may have to POST and I use some particular Link (defined by the Relation) for the "action" attribute).

The path through the system may be different between a user-browser and a user-machine but this is not a separation of implementation - it is REST! The state transfer happens how it needs to, how you define it. How users (in a browser) proceed.

"Finally, by separating the site from the API, you allow for different scaling needs. If your API is getting hit hard but not the website, you can throw more hardware at the API while keeping the minimal needed for the website." - your scaling should not depend on who uses what here. Odds are you're doing some work behind the scenes that is more intense than just serving up HTML. By using the same implementation, scaling is even easier. The API itself (the marshaling between XML and domain objects and back) is not going to exceed the business logic and processing, database, etc.

Lastly, by keeping them the same, it is much easier to think about your system as a whole. In fact, start with the HTML. Define the relationships. If you're having a hard time expressing a particular action or user story in HTML anchors and forms, you're probably straying from REST.

Remember, you're expressing things as links (of a particular relation) to other things. Those URIs can even be different depending on whether you're producing XML or HTML - the HTML page might POST to URI some/uri/a and the API might POST to some/uri/b - that's irrelevant and being concerned with what the actual URI contents are is the dark path to POX and RPC

Another nifty feature is that if you do it this way, you're not dependent on JavaScript. You've defined your system to work with basic HTML and you can 'flip on' JavaScript when it is available. Then you're really working with your "API" anyway (I cringe at referring to them as different things, but I'm also trying to bridge my response in to your wording)

** I will add one final comment, when producing HTML, I use 303 instead of 201 in order to facilitate POST-then-GET. If JS is enabled, you're actually talking XML (or JSON) and you're back to 201.

like image 31
Doug Moscrop Avatar answered Nov 10 '22 00:11

Doug Moscrop