libzeep

PrevUpHomeNext

REST Controller (CRUD)

The previous example is a rough example on how to use the rest_controller, it assumes you pass in the parameters using form data or query parameters. There's another approach, that is more elegant and easier for the developer: create a CRUD interface and pass the data encoded in JSON format.

To make this work, we rework the previous example. The data items Cart and Item remain the same, they already have a serialize method. The real difference is in the JavaScript code, in the previous example all work was done by the server, the JavaScript only called separate methods to fill the items list and the server responded with the new Cart content. In this example however, management of the cart content is done by the JavaScript and the updated cart is then sent using a PUT to the server.

The server therefore looks like this:

class shop_rest_controller : public zeep::http::rest_controller
{
  public:
    shop_rest_controller()
        : zeep::http::rest_controller("/cart")
    {
        // CRUD example interface

        map_post_request("",        &shop_rest_controller::create_cart, "cart");
        map_get_request("{id}",     &shop_rest_controller::retrieve_cart, "id");
        map_put_request("{id}",     &shop_rest_controller::update_cart, "id", "cart");
        map_delete_request("{id}",  &shop_rest_controller::delete_cart, "id");
    }

    int create_cart(Cart cart)
    {
        int result = cart.id = sNextCartID++;
        m_carts.push_back(std::move(cart));
        return result;
    }

    Cart& retrieve_cart(int cartID)
    {
        auto oi = std::find_if(m_carts.begin(), m_carts.end(), [&](auto& o) { return o.id == cartID; });
        if (oi == m_carts.end())
            throw std::invalid_argument("No such cart");
        return *oi;
    }

    void update_cart(int cartID, const Cart& cart)
    {
        auto oi = std::find_if(m_carts.begin(), m_carts.end(), [&](auto& o) { return o.id == cartID; });
        if (oi == m_carts.end())
            throw std::invalid_argument("No such cart");

        oi->client = cart.client;
        oi->items = cart.items;
    }

    void delete_cart(int cartID)
    {
        m_carts.erase(std::remove_if(m_carts.begin(), m_carts.end(), [cartID](auto& cart) { return cart.id == cartID; }), m_carts.end());
    }

  private:
    static int sNextCartID;
    std::vector<Cart> m_carts;
};

Some ceveats: this works probably only well if you have a single JSON (or compatible) data type as main parameter and optionally one or more path parameters. The request should also have content-type equal to application/json to work properly.


PrevUpHomeNext