Skip to content

Commit 067be92

Browse files
committed
Split response objects
1 parent 81256c0 commit 067be92

File tree

10 files changed

+197
-168
lines changed

10 files changed

+197
-168
lines changed

bid.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package openrtb
2+
3+
// ID, Impid and Price are required; all other optional.
4+
// If the bidder wins the impression, the exchange calls notice URL (nurl)
5+
// a) to inform the bidder of the win;
6+
// b) to convey certain information using substitution macros.
7+
// Adomain can be used to check advertiser block list compliance.
8+
// Cid can be used to block ads that were previously identified as inappropriate.
9+
// Substitution macros may allow a bidder to use a static notice URL for all of its bids.
10+
type Bid struct {
11+
Id *string `json:"id"`
12+
Impid *string `json:"impid"` // Required string ID of the impression object to which this bid applies.
13+
Price *float32 `json:"price"` // Bid price in CPM. Suggests using integer math for accounting to avoid rounding errors.
14+
Adid *string `json:"adid,omitempty"` // References the ad to be served if the bid wins.
15+
Nurl *string `json:"nurl,omitempty"` // Win notice URL.
16+
Adm *string `json:"adm,omitempty"` // Actual ad markup. XHTML if a response to a banner object, or VAST XML if a response to a video object.
17+
Adomain []string `json:"adomain,omitempty"` // Advertiser’s primary or top-level domain for advertiser checking; or multiple if imp rotating.
18+
Iurl *string `json:"iurl,omitempty"` // Sample image URL.
19+
Cid *string `json:"cid,omitempty"` // Campaign ID that appears with the Ad markup.
20+
Crid *string `json:"crid,omitempty"` // Creative ID for reporting content issues or defects. This could also be used as a reference to a creative ID that is posted with an exchange.
21+
Attr []int `json:"attr,omitempty"` // Array of creative attributes.
22+
Ext Extensions `json:"ext,omitempty"`
23+
}
24+
25+
// Validate Bid required attributes
26+
func (bid *Bid) Valid() (bool, error) {
27+
28+
if bid.Id == nil {
29+
return false, errValidationBidId
30+
} else if bid.Impid == nil {
31+
return false, errValidationBidImpid
32+
} else if bid.Price == nil {
33+
return false, errValidationBidPrice
34+
}
35+
36+
return true, nil
37+
}
38+
39+
// Set the ID
40+
func (bid *Bid) SetID(id string) *Bid {
41+
if bid.Id == nil {
42+
bid.Id = new(string)
43+
}
44+
*bid.Id = id
45+
return bid
46+
}
47+
48+
// Set the ImpID
49+
func (bid *Bid) SetImpID(id string) *Bid {
50+
if bid.Impid == nil {
51+
bid.Impid = new(string)
52+
}
53+
*bid.Impid = id
54+
return bid
55+
}
56+
57+
// Set the Price
58+
func (bid *Bid) SetPrice(p float32) *Bid {
59+
if bid.Price == nil {
60+
bid.Price = new(float32)
61+
}
62+
*bid.Price = p
63+
return bid
64+
}

bid_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package openrtb
2+
3+
import (
4+
"github.com/stretchr/testify/assert"
5+
"testing"
6+
)
7+
8+
func TestBid_Valid(t *testing.T) {
9+
bid := &Bid{}
10+
11+
ok, err := bid.Valid()
12+
assert.Equal(t, ok, false)
13+
if err != nil {
14+
assert.Equal(t, err.Error(), "openrtb response: bid is missing ID")
15+
}
16+
17+
bid.SetID("BIDID")
18+
ok, err = bid.Valid()
19+
assert.Equal(t, ok, false)
20+
if err != nil {
21+
assert.Equal(t, err.Error(), "openrtb response: bid is missing impression ID")
22+
}
23+
24+
bid.SetImpID("IMPID")
25+
ok, err = bid.Valid()
26+
assert.Equal(t, ok, false)
27+
if err != nil {
28+
assert.Equal(t, err.Error(), "openrtb response: bid is missing price")
29+
}
30+
31+
bid.SetPrice(0.0)
32+
ok, err = bid.Valid()
33+
assert.Equal(t, ok, true)
34+
}

impression.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package openrtb
22

3+
import (
4+
"errors"
5+
)
6+
37
// The "imp" object describes the ad position or impression being auctioned. A single bid request
48
// can include multiple "imp" objects, a use case for which might be an exchange that supports
59
// selling all ad positions on a given page as a bundle. Each "imp" object has a required ID so that
@@ -19,19 +23,26 @@ type Impression struct {
1923
Ext Extensions
2024
}
2125

26+
// Validation errors
27+
var (
28+
invalidImpId = errors.New("openrtb parse: impression ID missing")
29+
invalidImpBoV = errors.New("openrtb parse: impression has neither a banner nor video")
30+
invalidImpBaV = errors.New("openrtb parse: impression has banner and video")
31+
)
32+
2233
// Validates the `imp` object
2334
func (imp *Impression) Valid() (bool, error) {
2435

2536
if imp.Id == nil {
26-
return false, errValidationImpId
37+
return false, invalidImpId
2738
} else if imp.Banner != nil && imp.Video != nil {
28-
return false, errValidationImpBaV
39+
return false, invalidImpBaV
2940
} else if imp.Video != nil {
3041
if ok, err := imp.Video.Valid(); !ok {
3142
return ok, err
3243
}
3344
} else {
34-
return false, errValidationImpBoV
45+
return false, invalidImpBoV
3546
}
3647

3748
return true, nil

openrtb.go

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -51,40 +51,9 @@ const (
5151
VIDEO_QUALITY_UGC = 3
5252
)
5353

54-
// At least one of Bid is required.
55-
// A bid response can contain multiple “seatbid” objects, each on behalf of a different bidder seat.
56-
// Seatbid object can contain multiple bids each pertaining to a different impression on behalf of a seat.
57-
// Each “bid” object must include the impression ID to which it pertains as well as the bid price.
58-
// Group attribute can be used to specify if a seat is willing to accept any impressions that it can win (default) or if it is
59-
// only interested in winning any if it can win them all (i.e., all or nothing).
60-
type Seatbid struct {
61-
Bid []Bid `json:"id"` // Array of bid objects; each realtes to an imp, if exchange supported can have many bid objects.
62-
Seat *string `json:"seat,omiempty"` // ID of the bidder seat optional string ID of the bidder seat on whose behalf this bid is made.
63-
Group *int `json:"group,omiempty"` // '1' means impression must be won-lost as a group; default is '0'.
64-
Ext Extensions `json:"ext,omiempty"`
65-
}
66-
67-
// ID, Impid and Price are required; all other optional.
68-
// If the bidder wins the impression, the exchange calls notice URL (nurl)
69-
// a) to inform the bidder of the win;
70-
// b) to convey certain information using substitution macros.
71-
// Adomain can be used to check advertiser block list compliance.
72-
// Cid can be used to block ads that were previously identified as inappropriate.
73-
// Substitution macros may allow a bidder to use a static notice URL for all of its bids.
74-
type Bid struct {
75-
Id *string `json:"id"`
76-
Impid *string `json:"impid"` // Required string ID of the impression object to which this bid applies.
77-
Price *float32 `json:"price"` // Bid price in CPM. Suggests using integer math for accounting to avoid rounding errors.
78-
Adid *string `json:"adid,omitempty"` // References the ad to be served if the bid wins.
79-
Nurl *string `json:"nurl,omitempty"` // Win notice URL.
80-
Adm *string `json:"adm,omitempty"` // Actual ad markup. XHTML if a response to a banner object, or VAST XML if a response to a video object.
81-
Adomain []string `json:"adomain,omitempty"` // Advertiser’s primary or top-level domain for advertiser checking; or multiple if imp rotating.
82-
Iurl *string `json:"iurl,omitempty"` // Sample image URL.
83-
Cid *string `json:"cid,omitempty"` // Campaign ID that appears with the Ad markup.
84-
Crid *string `json:"crid,omitempty"` // Creative ID for reporting content issues or defects. This could also be used as a reference to a creative ID that is posted with an exchange.
85-
Attr []int `json:"attr,omitempty"` // Array of creative attributes.
86-
Ext Extensions `json:"ext,omitempty"`
87-
}
54+
/*************************************************************************
55+
* COMMON OBJECT STRUCTS
56+
*************************************************************************/
8857

8958
// This object may be useful in the situation where syndicated content contains impressions and
9059
// does not necessarily match the publisher’s general content. The exchange might or might not

request.go

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,6 @@ import (
66
"io"
77
)
88

9-
var (
10-
errValidationReqId = errors.New("openrtb parse: request ID missing")
11-
errValidationReqImp = errors.New("openrtb parse: no impressions")
12-
errValidationReqSaA = errors.New("openrtb parse: request has site and app")
13-
errValidationImpId = errors.New("openrtb parse: impression ID missing")
14-
errValidationImpBoV = errors.New("openrtb parse: impression has neither a banner nor video")
15-
errValidationImpBaV = errors.New("openrtb parse: impression has banner and video")
16-
errValidationVideoMimes = errors.New("openrtb parse: video has no mimes")
17-
errValidationVideoLinearity = errors.New("openrtb parse: video linearity missing")
18-
errValidationVideoMinduration = errors.New("openrtb parse: video minduration missing")
19-
errValidationVideoMaxduration = errors.New("openrtb parse: video maxduration missing")
20-
errValidationVideoProtocol = errors.New("openrtb parse: video protocol missing")
21-
)
22-
239
// The top-level bid request object contains a globally unique bid request or auction ID. This "id"
2410
// attribute is required as is at least one "imp" (i.e., impression) object. Other attributes are
2511
// optional since an exchange may establish default values.
@@ -60,14 +46,21 @@ func ParseRequestBytes(data []byte) (req *Request, err error) {
6046
return req.WithDefaults(), nil
6147
}
6248

49+
// Validation errors
50+
var (
51+
invalidReqId = errors.New("openrtb parse: request ID missing")
52+
invalidReqImp = errors.New("openrtb parse: no impressions")
53+
invalidReqSaA = errors.New("openrtb parse: request has site and app")
54+
)
55+
6356
// Validates the request
6457
func (req *Request) Valid() (bool, error) {
6558
if req.Id == nil {
66-
return false, errValidationReqId
59+
return false, invalidReqId
6760
} else if len(req.Imp) == 0 {
68-
return false, errValidationReqImp
61+
return false, invalidReqImp
6962
} else if req.Site != nil && req.App != nil {
70-
return false, errValidationReqSaA
63+
return false, invalidReqSaA
7164
}
7265

7366
for _, imp := range req.Imp {

response.go

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -51,66 +51,3 @@ func (res *Response) Valid() (bool, error) {
5151

5252
return true, nil
5353
}
54-
55-
// Seatbid methods
56-
57-
// Validate Seatbid required attributes
58-
// @return [Boolean,Error]
59-
func (sb *Seatbid) Valid() (bool, error) {
60-
61-
if sb.Bid == nil || len(sb.Bid) < 1 {
62-
return false, errValidationSeatbidBid
63-
}
64-
65-
for _, bid := range sb.Bid {
66-
if ok, err := bid.Valid(); !ok {
67-
return ok, err
68-
}
69-
}
70-
71-
return true, nil
72-
}
73-
74-
// Bid methods
75-
76-
// Validate Bid required attributes
77-
// @return [Boolean,Error]
78-
func (bid *Bid) Valid() (bool, error) {
79-
80-
if bid.Id == nil {
81-
return false, errValidationBidId
82-
} else if bid.Impid == nil {
83-
return false, errValidationBidImpid
84-
} else if bid.Price == nil {
85-
return false, errValidationBidPrice
86-
}
87-
88-
return true, nil
89-
}
90-
91-
// Set the ID
92-
func (bid *Bid) SetID(id string) *Bid {
93-
if bid.Id == nil {
94-
bid.Id = new(string)
95-
}
96-
*bid.Id = id
97-
return bid
98-
}
99-
100-
// Set the ImpID
101-
func (bid *Bid) SetImpID(id string) *Bid {
102-
if bid.Impid == nil {
103-
bid.Impid = new(string)
104-
}
105-
*bid.Impid = id
106-
return bid
107-
}
108-
109-
// Set the Price
110-
func (bid *Bid) SetPrice(p float32) *Bid {
111-
if bid.Price == nil {
112-
bid.Price = new(float32)
113-
}
114-
*bid.Price = p
115-
return bid
116-
}

response_test.go

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -47,49 +47,3 @@ func TestResponse_Valid(t *testing.T) {
4747
assert.Equal(t, ok, true)
4848
assert.Nil(t, err)
4949
}
50-
51-
func TestSeatbid_Valid(t *testing.T) {
52-
sb := &Seatbid{}
53-
54-
ok, err := sb.Valid()
55-
assert.Equal(t, ok, false)
56-
if err != nil {
57-
assert.Equal(t, err.Error(), "openrtb response: seatbid is missing bids")
58-
}
59-
60-
bid := &Bid{}
61-
bid.SetID("BIDID").SetImpID("IMPID").SetPrice(0.0)
62-
sb.Bid = append(sb.Bid, *bid)
63-
64-
ok, err = sb.Valid()
65-
assert.Equal(t, ok, true)
66-
assert.Nil(t, err)
67-
}
68-
69-
func TestBid_Valid(t *testing.T) {
70-
bid := &Bid{}
71-
72-
ok, err := bid.Valid()
73-
assert.Equal(t, ok, false)
74-
if err != nil {
75-
assert.Equal(t, err.Error(), "openrtb response: bid is missing ID")
76-
}
77-
78-
bid.SetID("BIDID")
79-
ok, err = bid.Valid()
80-
assert.Equal(t, ok, false)
81-
if err != nil {
82-
assert.Equal(t, err.Error(), "openrtb response: bid is missing impression ID")
83-
}
84-
85-
bid.SetImpID("IMPID")
86-
ok, err = bid.Valid()
87-
assert.Equal(t, ok, false)
88-
if err != nil {
89-
assert.Equal(t, err.Error(), "openrtb response: bid is missing price")
90-
}
91-
92-
bid.SetPrice(0.0)
93-
ok, err = bid.Valid()
94-
assert.Equal(t, ok, true)
95-
}

seatbid.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package openrtb
2+
3+
// At least one of Bid is required.
4+
// A bid response can contain multiple “seatbid” objects, each on behalf of a different bidder seat.
5+
// Seatbid object can contain multiple bids each pertaining to a different impression on behalf of a seat.
6+
// Each “bid” object must include the impression ID to which it pertains as well as the bid price.
7+
// Group attribute can be used to specify if a seat is willing to accept any impressions that it can win (default) or if it is
8+
// only interested in winning any if it can win them all (i.e., all or nothing).
9+
type Seatbid struct {
10+
Bid []Bid `json:"id"` // Array of bid objects; each realtes to an imp, if exchange supported can have many bid objects.
11+
Seat *string `json:"seat,omiempty"` // ID of the bidder seat optional string ID of the bidder seat on whose behalf this bid is made.
12+
Group *int `json:"group,omiempty"` // '1' means impression must be won-lost as a group; default is '0'.
13+
Ext Extensions `json:"ext,omiempty"`
14+
}
15+
16+
// Validate Seatbid required attributes
17+
func (sb *Seatbid) Valid() (bool, error) {
18+
19+
if sb.Bid == nil || len(sb.Bid) < 1 {
20+
return false, errValidationSeatbidBid
21+
}
22+
23+
for _, bid := range sb.Bid {
24+
if ok, err := bid.Valid(); !ok {
25+
return ok, err
26+
}
27+
}
28+
29+
return true, nil
30+
}

0 commit comments

Comments
 (0)