I was wondering what would be the best approach to make a Grails app offer a RESTful API (some CRUD actions mainly) that can be used by a web service, e.g. when you want to build a corresponding iOS app to your browser-based app or anything else.
I thought of building a separate part in my Grails application that takes calls from www.mywebapp.com/api/someAction so that I can reuse the Service layer. How would I do the URL mapping then? Only having one big ApiController does not sound very groovy.
Or is there any better approach I did not know of? This approach must support something like OAuth to authenticate the user who is calling the Web service.
Grails can definitely provide a REST api, but the level of difficulty in doing so varies depending on how mature (aka. how RESTful) you want the API to be.
Basic REST
Getting a basic level of RESTfullness, where you are manipulating json or xml representations of resources using the full span of HTTP verbs and leveraging the HTTP response codes, is pretty easy. There are 3 main pieces to getting that in place:
URL mapping
Here's an example of how I wrote my URL mappings on a recent project to allow for more RESTful URLs:
// RESTful list mapping
name restEntityList: "/$controller"(parseRequest: true) {
action = [GET: "list", POST: "save"]
}
// RESTful entity mapping
name restEntity: "/$controller/$id"(parseRequest: true) {
action = [GET: "show", PUT: "update", POST: "update", DELETE: "delete"]
constraints {
id matches: /\d+/
}
}
Content negotiation
The 3 different ways that Grails can handle content negotiation make the framework very flexible, allowing you to support a much broader range of clients who may not be able to set things like the Accept HTTP header.
You can use the content negotiation to respond to different requests in different ways using the withFormat block based on what the client has indicated they want. This powerful ability can also be used to version your API, much like how Github does.
Response status
HTTP already has a great response mechanism built into it that allows you to leverage innate abilities in the architecture, like cacheability and indemnipotent operations. While some web browsers don't handle certain response codes very gracefully, client applications using your API can use them to greatly simplify their internal code.
DRY REST
One of the best ways to make your application RESTful and keep it DRY at the same time is to leverage the controller scaffolding as much as possible, since CRUD is essentially the same for all domain objects. This article on making the default controller more RESTful, and this article on simplifying the default controller are both great resources for getting more power from the scaffolding.
Advanced REST
Once you get to that point, you have a pretty functional REST API for your grails application. You can do all basic CRUD operations and the resources are fairly easy to work with.
The next levels of the ladder to a true RESTful hypermedia API, however, are much harder to attain. Fixing this is on the road map for Grails, but currently it's rather painful. These pieces are:
Hypermedia resources
Content types
Versioning
Thankfully, there is a plugin that makes defining custom marshallers very easy, which allows us to fairly easily cover those three remaining pieces of the REST puzzle.
Finally, there is the aspect of securing the whole thing. In general, Spring Security will hold you in good stead as far as securing user-access to your api. Since most API access is from an application, and isn't user-visible, basic or digest authentication is usually the simplest way to go. There is an OAuth plugin that builds on Spring Security. I have not personally used it so I can't vouch for it's stability, but it looks pretty good to me.
In general, Grails is flexible and powerful enough to do REST very, very well, but the work has not been done yet to make it do REST cleanly out-of-the-box.
the grails documentation has a good walk though on setting up a RESTfull api
http://grails.org/doc/latest/guide/webServices.html#13.1
You can map it anyway, use any url structure. Grails UrlMapping is pretty flexible, it's only default behavior to map to /$controller/$action, but you can use your own mapping, you can event map each url manually, etc.
See UrlMapping docs - http://grails.org/doc/latest/guide/theWebLayer.html#urlmappings
url mapping:
"/api/element/$version/$master" {
controller = "element"
action = [GET:"show"]
}
This will map the http get to the show method of the controller element.
i.e. the show method:
DRY: The api is probably the same logic as the application. The difference is content negociation.
...
def show = {
def elements = elementService.findByMasterVersion(params.master, params.version)
withFormat {
xml {
render(status:200,text:elements as XML, contentType:"text/xml",encoding:"UTF-8")
}
json { ... }
html { ... }
}
}
Oauth is pretty damn complicated to implement and seems overkill for a lot of situation.
Related
I am using an PHP MVC framework (Yii, but my question could apply to most MVC frameworks) to create a project that should include a web application (website) and RESTful web service. I am facing an early design decision on how to logically separate the application and service logic. Here are some true facts:
The web app and web service will share a lot of functionality and only differ in rendered format (View vs JSON)...
...But, the web app and web service will have some unique features (ie, there will be things that the web app does that the service does not, and vice-versa)
Here are my desires:
I would like to share the common functionality's implementation as much as possible
I do not want the Controller to become unwieldy as a result of combining web service/web application logic
I have a a slight distaste for creating separate web service and web app controllers, especially when they overlap in Actions (other than the rendered format)
I do not want to have the web site consume the web service unless it is really a necessary design decision; I will lose out on a lot of built-in features that use database interfaces and/or have to create classes that conform to available IDataSource and other such interfaces by hooking it up to the web service; also there could be a slight performance decline.
I have thought about it a bit and come up with some solutions below. Please let me know which of these you think would meet my wants or let me know if my wants are not reasonable/counter-productive.
Implement completely separate controllers for WebApp and WebService (modularize the two so that they share no code)
Implement separate controllers for WebApp and WebService, but create methods that do the heavy lifting and call those methods to share implementation - for example, if I wanted to do a item/findBySomeCrazyCriteria I would route to the appropriate controller depending on the URL, but each controller would reference some FindItemsBySomeCrazyCriteriaFunction() defined elsewhere.
Make the web app consume the web service (which would require me to expand the planned functionality of the service)
Implement one controller for both WebApp and WebService, which extends from a BaseController that includes generic hooks for REST type stuff in terms of $this->getModel()` and use overrides where necessary
Anything else
Although my question is related to Yii, I feel like this must have come up in the past for many developers. I would like to know what you did/what you recommend to move forward. I am concerned that if I choose the wrong approach I will "break MVC" or somehow regret it later.
Note: you should not worry about "breaking the MVC". Since you have chosen to use Yii, that part has already happened.
The root of the problem lays in the fact that your controllers do a lot of stuff (and thus, violating SRP). What you call "controllers' actually contain also the application logic (that should be part of model layer) and UI logic (that normally would be part of view instances).
What you should have there is a single application, with one model layer and two presentations (what you refer to as "web application" and "web service"). The controllers should be a slight a possible.
You should move the application logic to the service layer through which then the presentation layer would interact with model. You would end up with a lot lighter controller. Then you could be able to provide a separate set of controllers/view for each of the presentations that your project needs with no or minor code duplication.
I would recommend against writing multiple controllers. It is a much better option to keep your domain logic in the models, rather than controllers. Your controllers should only act as the gateway to the logic and serve them in whatever form the client requests eg. as a JSON encoded response or through a view. It would be best if you just keep the task of identifying the client requirements and after obtaining the results from the model translating the response in an appropriate form.
This flow can be streamlined with suitable helpers and a well implemented routing sub-system so that detection of client requirements becomes effortless.
eg. /user/subscriptions.html will fetch an html page where as /user/subscriptions.json will fetch a JSON response.
I'm currently developing a web application, that relies heavily on mobile and desktop clients consulting the web server for information. This can be accomplished nicely making a RESTful API available to handle this. So my idea is to have an application acting as the "platform" which handles all the real business logic and database information behind the curtains.
My plan is to make the platform using symfony2 and OAuth 2.0 authentication mechanisms, combined with RESTful web services.
Now my real dilema comes on the website component. Ideally I would like to think of the website as yet another client that asks this REST platform for information, and completely separate it from the platform itself.
To make it a little bit more clear, let's say we are making a blog with this architecture, so one would have a "platform/backend" that provides a rest service to list articles, for example: /articles/5. This on the backend, and with symfony2/doctrine means that the app has an Article model class, and these can be requested from the DB. A simple controller queries for the Article number 5 and returns all the information in JSON format.
Now the website on this example, could just do the easy thing and also have an Article entity and just query the database directly, but I think it would be cleaner if it could just talk to the platform through it's REST api and use that information as a "backend" for the entities.
So the real question would be, is there anyway to support this kind of design using symfony2? Have entities rely on a REST api for CRUD operations? Or I'm just better off making the platform/website a single thing and share a "CoreBundle" with all the generic entities?
There is nothing in Symfony that prevents you from doing you want.
On the client side you could use Backbone.js or Spine.js.
Have a look at FosRestBundle, it makes your life much easier to create api:
https://github.com/FriendsOfSymfony/FOSRestBundle/blob/master/Resources/doc/index.md
I'm thinking of using RailwayJS to build my web server. Previously I was using express, which is considered to be RESTful. However, from what I've been reading, it seems that RailwayJS is not considered to be RESTful, even though it uses express!
What is it about RailwayJS that makes it not RESTful? If it passes messages using JSON doesn't that make it RESTful?
I'm curious where and/or how you drew your conclusions regarding REST and Express/RailwayJS?
Express allows you the freedom to set up your router any way you wish; you could very easily create a very RESTful style application, or you could very easily break every rule in the REST architecture. Express presents no opinion on you whatsoever.
RailwayJS, however, seems to favor a more RESTful style interface--at least, when using "REST" in the same context as you would in, say, Ruby on Rails. Railway supports resource based routing, which maps a resource to seven very Rails-like URLs/HTTP verbs:
Resource-based routing provides standard mapping between HTTP verbs and controller actions:
map.resources('posts');
will provide following routes:
helper | method | path | controller#action
---------------------------------------------------------------
posts GET /posts posts#index
posts POST /posts posts#create
new_post GET /posts/new posts#new
edit_post GET /posts/:id/edit posts#edit
post DELETE /posts/:id posts#destroy
post PUT /posts/:id posts#update
post GET /posts/:id posts#show
Thus my conclusion would be, when using "REST" in the context that most people do when designing MVC-based web applications, that Express can be RESTful, depending on how you design your app, but isn't inherently RESTful, and that RailwayJS prefers a RESTful setup (although you don't have to use resource-based routing in RailwayJS either).
I don't exactly know what RESTFUL is. Sure I know it's a mapping of a URL to a resource. But how's that different from an ajax call to a codeigniter URL which echos some JSON?
My application will have subscriptions with states/options, is there any reason I should be using a RESTful setup rather than just some ajax calls when a user switches some of the options for their subscriptions?
You should not necessarily use "pure" REST. If your requirements drive you towards an HTTP-based service returning JSON, then great. But that doesn't imply that you need other aspects of the REST architectural style. You may not need:
An architecture based on resources, in the sense they're defined by the HTTP protocol
A URL structure that maps to resources
You may not want the return result from one request to provide a set of URLs which indicate "where to go" for related requests.
REST is an architectural style, but it can also become a "religion". Be certain that whatever you do is driven by the requirements you need to fulfill, and not based on "ideology".
I see APIs such as PayPal, etc. offering to call their services using NVP or SOAP/WSDL. When using a .NET environment (3.5) using traditional web services (no WCF) which is better and why? I know WSDL lets you drop in the API URL and it generates the wrappers for you. So then why do companies even offer NVP?
There seems to be never-ending confusion in this industry about the different types of web services.
SOAP is a messaging protocol. It has as much in common with REST as an apple has with a lawn tractor. Some of the things you want in a messaging protocol are:
Headers and other non-content "attributes."
Addressing - routing of a message to different servers/recipients based on the headers;
Guaranteed delivery via queuing and other methods;
Encryption, signing, and other security features;
Transactions and orchestrations;
Accurate representation of complex structured data in a single message;
...and so on. This is not an exhaustive list. What WSDL adds to SOAP, primarily, is:
Discoverability via a contract, a form of machine-readable "documentation" that tells consumers exactly what is required in order to send a message and allows proxies to be auto-generated;
Strict, automated schema validation of messages, the same way XSD works for XML.
REST is not a messaging protocol. REST is a system of resources and actions. It is a solid choice for many architectures for several important reasons as outlined by other answers. It also has little to no relevance to "NVP" services like PayPal and flickr.
PayPal's NVP API is not REST. It is an alternative, RPC-like messaging protocol over HTTP POST for clients that don't support or have difficulty supporting SOAP. This isn't my opinion, it's a statement of fact. One of the fields in the NVP is actually METHOD. This is clearly RPC verbiage. Take a look at their API for UpdateRecurringPaymentsProfile and try to tell me that this makes a lick of sense to describe as a "resource". It's not a resource, it's an operation.
In the case of PayPal specifically, the "NVP" (HTTP POST) API is inferior to the SOAP API in almost every way. It is there for consumers who can't use SOAP. If you can use it, you definitely should.
And I'm not necessarily bashing PayPal for this, either. I know a lot of folks have bashed them for not putting together a "proper" RESTful API but that is not what I am getting at. Not every service in the world can be accurately described with REST. PayPal isn't really a resource-based system, it's a transactional system, so I can forgive their architects and developers for not having a perfectly elegant REST architecture. It's debatable perhaps, but it's not black-and-white. It's fine; I'll just use the SOAP system if I need to.
Compare this to, say, the Twitter API. This is a true REST service. Every "operation" you can perform on this API is accurately described as either the retrieval or submission of a particular kind of resource. A resource is a tweet, a status, a user. In this case it literally makes no sense to use a complex SOAP API because you're not really sending messages, you're not performing transactions, you're just asking for specific things, and these things can be described with a single URL. The only difference is that instead of getting an HTML web page back, you're getting some XML or JSON data; the way you request it is exactly the same.
A REST Web Service usually (always?) uses HTTP GET for the retrieval of some resource. And Twitter does exactly this. GET still uses "Name-Value Pairs" - that's the query string, ?q=twitterapi&show_user=true. Those bits after the ? are name-value pairs. And here's a great example of why you would want to use REST over SOAP; you can hook this up to an RSS feed and get streaming updates. I can turn it into a Live Bookmark in Firefox. Or I can download it in JSON format and bind it to something like a jqGrid. The interesting thing is not that the request uses "Name-Value Pairs"; the interesting thing is that it's a simple URL and can be consumed by anything that knows how to request a web page.
So to try and summarize all of what I've said, think of it this way:
Use a REST API (if available) when you want to expose data, or consume or publish it, as a permanent resource.
Use a SOAP API when the system is transactional in nature and/or when you need the advanced features that a complex messaging protocol can offer, such as RM and addressing.
Use an RPC API (which includes just about any API that's modeled entirely around HTTP POST) when there is no SOAP API or when you are unable to use the SOAP API.
Hope that clears up some of the confusion.
I assume that by Name Value Pairs, you mean REST services.
The benefits to REST are primarily ease of development, simplicity and elegance, and lower overhead (which is very important if you are sending and receiving a lot of small messages).
Here are some of the advantages of REST:
REST is more lightweight
Human readable results
Everything is a URI addressable resource
REST services are more easily cached
REST is easier to build (no toolkits are required)
REST is easier to call (HTTP - GET, POST, PUT, DELETE)
NVP is HTTP POST
name=fred
amount=100
code=403
etc
This is the default format from any HTML browser so it's simple to implement for sending data to a web service
I don't think it's a good format for receiving data from web service? JSON or XML would be more suitable
No everyone uses VisualStudio, or has access to automatic wrapper generators, or wants to use such a beast
Many web mashups are coded in Javascript, so using HTTP POST to send data is the simplest way. The return result is a standard HTML response code (200, 403, 500, etc) and/or some JSON
Many service providers offer multiple API's to cater for all customers