Skip to content

Customizing BidRequest and BidResponse

Vladimir Venediktov edited this page Aug 9, 2017 · 11 revisions

Vanilla by default uses DSL mapper from jsonv github project in its stack and zero-copy, zero-allocation json parsers located in vanilla-rtb/parsers directory.

DSL image

The mapper works with boost::optional and it allows us to have missing fields in the message as long as openrtb::BidRequest uses boost::optional for that field. However, if you decide to use std::optional it will work too provided you pass flags to cmake before you build jsonv under vanilla-rtb. if you are planning to use different openRTB version other then we ship with vanilla-rtb we recommend doing it the following way.

  • Your project should be independent from vanilla-rtb , you don't want to modify our code in your fork as we periodically update our stack especially examples folder.
  • Please use this cmake project https://github.com/vanilla-rtb/rapid-bidder as a model for your future project it pulls vanilla-rtb as github submodule however if you decide you don't want to wait for our fixes we recommend creating gh-subtree.
  • after you created directory outside of vanilla-rtb stack ( you can have same name directory DSL , placing under the root of your project , so in case of our model repository rapid-bidder it would be placed https://github.com/vanilla-rtb/rapid-bidder/ DSL
  • if you add new fields to your custom::BidRequest, and make them optional even though they are optional the DSL extractor needs to know how to map them in case they are received. So, if you see field in openrtb::BidRequest as optional , most likely we already provided DSL mapping code for them and you don't have to do anything , you can simply ignore sending this field in the message if this field not used in your message protocol. Basically if you see extra field don't rush to remove it may still work for you
  • depending on if your goal is low latency , then you should not keep a lot of optional unused fields as it effect performance of DSL mapper.

However if you decide to make very custom BidRequest not openRTB standard , this can be achieved by writing following code in your project's namespace.

weibo_dsl_mapper.hpp:

#include "path-to-your-file/weibo.hpp"
#include "core/openrtb.hpp" //If you need to reuse some classes from vanilla-rtb
#include <vector>
#include <boost/optional.hpp>

template<typename T>
class weibo_dsl_mapper {
 using deserialized_type = weibo::BidRequest<T>; //needed for GenericDSL
 using serialized_type   = weibo::BidResponse<T>; //needed for GenericDSL
 using parse_error_type  = jsonv::parse_error; //needed for GenericDSL
//Your other 'using'  
//and
//mapping code goes here
//follow our new rtb/DSL/dsl_mapper.hpp code for DSL mapping example
}; 

weibo.hpp:

//If you need to reuse some classes from vanilla-rtb
#include "rtb/core/openrtb.hpp"

namespace weibo {
      template<typename T>
      struct BidRequest {
        ~BidRequest() {}

        T id;                             // 请求id 由wax 系统产生
        std::vector<openrtb::Impression<T>> imp;     //曝光对象,一次request可以包含多个imp
        T dealid;            // wax系统给参与prefered deal的dsp分配的deal id
        std::vector<T> rule;  // 此次流量命中的在DMP系统中注册的ruleid
        boost::optional<openrtb::App> app;       //应用对象
        boost::optional<openrtb::Device> device; //设备对象
        boost::optional<openrtb::User<T>> user;  //用户对象
        AuctionType at;                 // 竞拍方式 2 二阶竞价
};
}

In your bidder now you should continue using vanilla class GenericDSL :

using DSLT = DSL::GenericDSL<std::string, weibo_dsl_mapper> ;

Sometimes during customization you may be able to refer to openrtb components like in above example openrtb::Impression openrtb::App However, if your product is not openRTB compliant then all bets are off you will have to create your own BidRequest / BidResponse suite of classes and also write your own custom DSL mapper weibo_dsl_mapper.hpp listed above. That's few hour job if you follow our code.