grails 3 rest-api profile GET - rest

I am using grails 3 rest-api profile. I created generated simple domain class
#Resource(readOnly = false, formats = ['json', 'xml'])
class User {
String name
String address
Date dateOfBirth
}
while http://localhost:8080/user/ will give me back json list of users, if I try http://localhost:8080/user/1 if gives back :
{"message":"Not Found","error":404}
what gives ?

actually I since found out that the url exposed is /user/show/1
since RestResource automatically exposes a controller based on grails.rest.RestfulController you can look in that class for the full list of methods

seems to be a bug. If you specify a uri it works:
#Resource(uri='/user/', readOnly = false, formats = ['json', 'xml'])
class User {
String name
String address
Date dateOfBirth
}

Related

Getting method name related to a rest service

I wanted to know if there exist a way of retrieving the actual method name associated to a rest service provided. Lets suppose my url is http://localhost:8080/v1/mytesturl now i want to retrieve the actual method name that is associated with this url.
Actually we are maintaining some key/value pair specific to the method that we have created and i need to make some checks based on the method name that gets executed using these values.
Plz let me know if there exist some way to do that..
Simply get the method name from the Object class.
#RestController
#RequestMapping("")
public class HomeController {
#RequestMapping("/mytesturl")
#ResponseBody
public String getMethodName() {
return new Object(){}.getClass().getEnclosingMethod().getName();
}
}
i got the solution by using this
Map<RequestMappingInfo, HandlerMethod> handlerMethods = RequestMappingHandlerMapping.getHandlerMethods();
HandlerExecutionChain handler = RequestMappingHandlerMapping.getHandler(requestr);
HandlerMethod handler1 = null;
if(Objects.nonNull(handler)){
handler1 = (HandlerMethod) handler.getHandler();
handler1.getMethod().getName()
}
this provide me with what i wanted..

Finding a specific ID using Rest in Grails

I'm exploring the RESTful domain capabilities in Grails 3.1.4 and am getting odd results. For example, I have this domain object (and no corresponding controller):
package resttest
import grails.rest.*
#Resource(readOnly = false, formats = ['json', 'xml'])
class Book {
String name
}
Querying all objects seems to work OK:
$ curl http://localhost:8080/book
[{"id":1,"name":"The Time Machine"},{"id":2,"name":"Moby Dick"}]
But getting a specific object fails:
$ curl http://localhost:8080/book/1
{"message":"Not Found","error":404}
I must be doing something wrong, but simple I can't see it.
A valid uri needs to be provided in #Resource after which the endpoint can be accessed. I would use as below for a Book resource (note plural books instead of book).
import grails.rest.Resource
#Resource(uri = "/books", readOnly = false, formats = ['json', 'xml'])
class Book {
String name
}
Result:
$ curl http://localhost:8080/books
[{"id":1,"name":"The Time Machine"},{"id":2,"name":"Moby Dick"}]
$ curl http://localhost:8080/books/1
{"id":1,"name":"The Time Machine"}

Swagger-Springmvc: Getting unknownFields in JSON

I have a REST API which I have configured as follows
#Api(value="rest", description="Sweet blah!!!")
#Controller
public class abc{...}
A method in abc is annotated as follows
#ApiOperation(value="Create Account",
notes="Sweet Blah",
response=Account.class,
nickname="AccountCreation2",
produces= "application/json,application/xml",
consumes="application/json, application/xml")
#ApiImplicitParams(value=
{ #ApiImplicitParam(name="body",value="Sweet Blah.",
required=true, paramType="body", dataType="com.trrr.Account"),
#ApiImplicitParam(name="accountId", value="provides account Id for the new
account",required=true, paramType="path", dataType="Integer")
})
#RequestMapping(value = "/accounts/{accountId}", method = RequestMethod.PUT)
public ResponseEntity<?> createAccount(#PathVariable("accountId") Integer accountId,
#RequestBody Account acct){ ... }
My generated documentation using Swagger UI shows everything find however is unable to generated Model json for Account which is my model class.
Account is composed of few variables, in addition to an array of User Defined class 'Sharing'.
It is composed of another User defined class User.
Account class is annotated as follows:
#XStreamAlias("Account")
#XmlRootElement(name = "Account")
public class Account {... }
The generated documentation displays for Model Response and Request
**{
"unknownFields": {}
}**
Kindly guide as to what may be going wrong here. How to have a json version of Account object displayed. Thank you.
Well, the same thing worked on a next day. Not sure why it was not working on day one. Its appears idiotic but only purpose of me writing this is to ensure that nobody else doing the right way and gets confused with my post.

Unique Constraint over values of two domain classes in Grails

I have two domain classes. One is :
class User {
String login
String password
String firstName
String lastName
String address
String email
static constraints = {
login blank:false, size:5..15,matches:/[\S]+/, unique:true
password blank:false, size:5..15,matches:/[\S]+/
firstName blank:false
lastName blank:false
email email: true
}
}
And other is
class AddWebsite {
String website
User user
static constraints = {
website blank:false
website(unique: ['user'])
}
}
I am working with MongoDB at the backend. I need that for a particular login value, all siteURL values should be unique. Ex: login = abc#gmail.com. Then this user can have all unique url only in the database. But same urls can exist for different users. How do I do that using the unique constraint or any other approach?
Use embedded sub-documents to store SiteURL instances right inside the User. Then you define the collection to be a Set, which makes sure, all it's entries are unique. If you want to use the default mongo collection types or want to persist the order, define an interceptor like:
def beforeSave = {
urls = urls.unique()
}
UPDATE:
If your urls are plain strings, use the default primitive collection (no hasMany):
class User {
String login
//...
Set urls = new HashSet()
}
In this case you should be able to place unique constraint on the AddWebsite domain class such as this:
class AddWebsite {
String website
User user
static constraints = {
website(blank:false, unique: ['user'])
}
}
This will ensure that each website is unique in the database per user. Notice that multiple constraints are applied to the property website.
edited to match updated question.
It finally worked. I was getting the user cannot be null error while entering the website though it was not being validated in the AddWebsite domain class. I made the following changes and got it to work:
class AddWebsite{
String website
User user
static belongsTo = [user: User]
static constraints = {
website( url:true, unique: ['user'])
}
}
And in my controller also, I set the value of the user object to the session variable:
def addWebsites() {
if(request.method == 'POST') {
def w = new AddWebsite()
w.properties[
'website'
] = params
w.user = session["user"] //modified to make it work
if(w.save()) {
render view:'addWebsites', model:[message: "Successfully saved"]
}
else {
return [addWebsite:w]
}
}
Hope it helps someone :)

values cannot be entered for List<String> in create page of grails

This is the domain class:
package com.sample
class Person {
String id
String name
Integer age
Address address
List children
static hasMany = [pets:Pet, children: String, aliases : Alias]
static mapWith = "mongo"
static constraints = {
address nullable:true
}
}
This is the the create page of the app:
Can someone please tell me how I can get a list to write in the create Person page and a list editable in the edit Person page. (I'm using generated views by the command grails generate-view com.sample.Person)
First, you don't need the List children in domain class. But I'm not sure if grails supports scaffolding for relations with basic non-domain types (String in your case). If removing the list wouldn't help you will need to handle this situation manually.