0
votes

I know the basic principle of Restful API design. I just want to know what I'm gonna do it with Grails3 URL mapping against multiple search actions.

I created the grails(3.3.9) app with the profile rest-API. The default UrlMapping.groovy looks like this.

class UrlMappings {
    static mappings = {
        delete "/$controller/$id(.$format)?"(action:"delete")
        get "/$controller(.$format)?"(action:"index")
        get "/$controller/$id(.$format)?"(action:"show")
        post "/$controller(.$format)?"(action:"save")
        put "/$controller/$id(.$format)?"(action:"update")
        patch "/$controller/$id(.$format)?"(action:"patch")

        "/"(controller: 'application', action:'index')
        "500"(view: '/error')
        "404"(view: '/notFound')
    }
}

Domain Class Example

class ProductSanpshot {
    String id
    Float price
    String name
}

class Order {
    String id
    String status
    Float totalPrice
    User createdBy
    List<ProductSanpshot> ProductSanpshots
    String remark
    Date dateCreated
}

class User {
    String id
    String name
}

Controller Example

class OrderController {
    def index() {
        respond(Order.list())
    }

    def show() {
        respond(Order.get(params.id))
    }
}

Based on the URL mapping set which satisfies the basic principle of the Restful design:

  • When I access /order it would return the order list.
  • When I access /order/1 it would return the order detail with id value 1.

My questions are: Normally, we just don't get the order full list but with different parameters. How can I map the URL to retrieve the order within a particular price range? The normal implementation would look like this:

class OrderController {
    def index() {
        respond(Order.list())
    }

    def show() {
        respond(Order.get(params.id))
    }

    def getByPriceRange() {
        def minPrice = params.float("minPrice")
        def maxPrice = params.float("maxPrice")
        def result = Order.findAllByTotalPriceBetween(minPrice, maxPrice)

        respond(result)
    }
}

I would access order/getByPriceRange?minPrice=100&maxPrice=200.

I know this might not be so restful.

For default Grails url mapping I will get 404 error. It only maps http get to two actions to each controller. The index and show. And I don't think I have to map each controllers' actions one by one explicitly.

get "/$controller(.$format)?"(action:"index")
get "/$controller/$id(.$format)?"(action:"show")

The other scenarios are:

  • Get the orders by the status.
  • Get the order's all product snapshots.
  • Update the order's status
  • Update the order's remark

What should I do with the UrlMapping to fulfill these needs by the restful way?

Thanks in advance.

1

1 Answers

0
votes

I think you are wrong about that and the url is still restful. Since it is a get request, you have to send your parameters in url. And it is good for several reasons. For example when you add that url to bookmarks, you will get the same result with the desired data without any problem (Especially if this url referring to a page). For my projects I am using National Bank of Belgium's rest api design guide. This was the most detailed guide that I can find and I really like it. You can see that they are using limit and offset parameters for pagination and sort parameter for sorting. In your example it is more like a search operation. Of course there are a lot of approach and I know about pretty much all of them but I really like their approach. I use FIQL for the searches. You can read about it Search/Advanced search section. I don't want to use different parameters for search so I use it like :

someUrl?q=minPrice=gt=10;maxPrice=lt=50

Could not find any library that I like so I wrote my own parser to resolve that. Anyway these are my opinions and as I can see there is no standard for these. I hope it helps and free free to ask anything. Cheers !!