问题
I've built my first grails application. My URL mappings are what the default application provides:
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
}
Senario
I have a controller called ColorController with actions save and list. It simply does something like this:
def save () {
def colorInstance = new Color(params)
colorInstance.save(flush: true)
}
def list () {
[colorList: Color.list, colorTotal: Color.count()]
}
I would like to build a simple API for these actions.
- The save action should accept parameters as JSON and provide a successful message if the records save.
- The list action should provide the list as JSON
Questions
- Should I make a separate URL mapping for api? (e.g.
http://<domain>/<app>/rest/controller/action) - Should I be making a separate controller for my API's
- I am using spring security plugin for authentication. But at some point I might want to authenticate the restful api as well. What are some solutions for that?
- If I use the same controller, how can I modify these simple actions to do what I need.
回答1:
Before even looking below for my opinion/answers I would suggest to visit this SO Question for the basic understanding of RESTful WS in Grails.
Opinions:
"The save action should accept parameters as JSON and provide a successful message if the records save" - Save is mapped to POST RESTful. Instead of binding a JSON body to
paramsit is bound to therequest. In order to access the JSON object you just need to userequest.JSONin the action method.request.JSON instanceof JSONObject- "The list action should provide the list as JSON" -
list()action is mapped to a GET Request and you can render the map as JSON in thelist()as below
//Controller list()
import grails.converter.JSON
def list () {
[colorList: Color.list, colorTotal: Color.count()] as JSON
}
Answers to Questions:-
- Should I make a separate URL mapping for api?
Abiding by the basics of REST, the client should only access the resource (
Colorin this case) and should not bother about the underlyingcontrolleroraction. The server side logic should be abstracted from the client. URL Mapping is what the client would use to as form of request. I would have something like this in my url mapping forColorResource.
/color/$id?(resource: "color")
or
/color/$id?(controller: 'color'){
action = [GET: "list", POST: "save"]
}
Should I be making a separate controller for my API's? - Depends on the way the App is designed. You also can have the above controller as the API. For example, currently I am working on a grails app which used
AngularJSin the front End which connects to the Grails APP RESTFully. In order to achieve I had aRestClientControllerwhich works as an API to Angular. The rationale behind having a REST api in the same app is that in future we can expose the underlying service to external clients other than theAngularclient present in the app itself.I am using spring security plugin for authentication. But at some point I might want to authenticate the restful api as well. What are some solutions for that? - You can use Spring Security here as well. In my case I am using the plugin and I secure the
controllerby using the plugin's annotated component@Secured. I have customOAuthenabled as well for authorization which interacts to the company wide LDAP and AD Groups.If I use the same controller, how can I modify these simple actions to do what I need. - I think you would have got the answer to this question by now (after going through the SO question I mentioned above). Here is my opinion,
controlleractionscan route to appropriateserviceclasses which does the business implementations based on the request parameters.
For example,
//Action
def show(){
if(params.id){
colorService.getColor()
} else {
colorService.searchColor()
}
}
In the above example, the url mapping would be /color/123 or /color. In the former case, it will get the color and in the later it will search the colors
来源:https://stackoverflow.com/questions/16362322/what-is-an-efficient-way-to-create-manage-restful-api-with-grails