Skip to content

Commit cfe19cc

Browse files
feat: Added Data residency for eu and global region (#1104)
* feat: added data residency for eu and global region * feat: added data residency for eu and global region * docs: added set region use case * Update USE_CASES.md
1 parent 9335dca commit cfe19cc

File tree

4 files changed

+190
-0
lines changed

4 files changed

+190
-0
lines changed

USE_CASES.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This documentation provides examples for specific use cases. Please [open an iss
1010
- [Send an Email to Multiple Recipients](#send-an-email-to-multiple-recipients)
1111
- [Send Multiple Emails to Multiple Recipients](#send-multiple-emails-to-multiple-recipients)
1212
- [Send Multiple Emails with Personalizations](#multiple-email-personalizations)
13+
- [Set Region](#set-region)
1314
- [Transactional Templates](#transactional-templates)
1415
- [Legacy Templates](#legacy-templates)
1516
- [Send an Email With Twilio Email (Pilot)](#send-an-email-with-twilio-email-pilot)
@@ -1172,6 +1173,23 @@ try {
11721173
}
11731174
```
11741175

1176+
<a name="set-region"></a>
1177+
# Set Region
1178+
The SendGrid object can also be used to set the region to "eu", which will send the request to https://api.eu.sendgrid.com/. By default, it is set to https://api.sendgrid.com/, e.g.
1179+
1180+
```php
1181+
<?php
1182+
// Uncomment next line if you're not using a dependency loader (such as Composer)
1183+
// require_once '<PATH TO>/sendgrid-php.php';
1184+
1185+
$sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY'));
1186+
$sendgrid->setDataResidency("eu");
1187+
1188+
OR
1189+
1190+
$sendgrid->setDataResidency("global");
1191+
```
1192+
11751193
<a name="transactional-templates"></a>
11761194
# Transactional Templates
11771195

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
// index.php
3+
require_once __DIR__ . '/../../sendgrid-php.php';
4+
5+
use SendGrid\Mail\Mail;
6+
use SendGrid\Mail\Personalization;
7+
use SendGrid\Mail\To;
8+
$exceptionMessage = 'Caught exception: ';
9+
10+
////////////////////////////////////////////////////
11+
// Set data residency to navigate to a region/edge. #
12+
// sending to global data residency
13+
14+
$email = buildHelloEmail();
15+
$sendgrid = buildSendgridObject("global");
16+
17+
try {
18+
$response = $sendgrid->client->mail()->send()->post($email);
19+
print $response->statusCode() . "\n";
20+
print_r($response->headers());
21+
print $response->body() . "\n";
22+
} catch (Exception $e) {
23+
echo $exceptionMessage, $e->getMessage(), "\n";
24+
}
25+
26+
////////////////////////////////////////////////////
27+
// sending to EU data residency
28+
29+
$sendgrid_eu = buildSendgridObject("eu");
30+
31+
try {
32+
$response = $sendgrid_eu->client->mail()->send()->post($email);
33+
print $response->statusCode() . "\n";
34+
print_r($response->headers());
35+
print $response->body() . "\n";
36+
} catch (Exception $e) {
37+
echo $exceptionMessage, $e->getMessage(), "\n";
38+
}
39+
40+
////////////////////////////////////////////////////
41+
// not configuring any region defaults to global
42+
$sendgrid_default = new \SendGrid(getenv('SENDGRID_API_KEY'));
43+
try {
44+
$response = $sendgrid_default->client->mail()->send()->post($email);
45+
print $response->statusCode() . "\n";
46+
print_r($response->headers());
47+
print $response->body() . "\n";
48+
} catch (Exception $e) {
49+
echo $exceptionMessage, $e->getMessage(), "\n";
50+
}
51+
52+
function buildHelloEmail(): Mail
53+
{
54+
$email = new Mail();
55+
$email->setFrom("test@example.com", "test");
56+
$email->setSubject("Sending with Twilio SendGrid is Fun");
57+
$email->addTo("test@example.co", "test");
58+
$email->addContent("text/plain", "and easy to do anywhere, even with PHP");
59+
$email->addContent(
60+
"text/html", "<strong>and easy to do anywhere, even with PHP</strong>"
61+
);
62+
$objPersonalization = new Personalization();
63+
64+
$objTo = new To('foo@bar.com', 'foo bar');
65+
$objPersonalization->addTo($objTo);
66+
$email->addPersonalization($objPersonalization);
67+
return $email;
68+
}
69+
70+
function buildSendgridObject($region): SendGrid
71+
{
72+
$sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY'));
73+
$sendgrid->setDataResidency($region);
74+
return $sendgrid;
75+
}

lib/BaseSendGridClientInterface.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ abstract class BaseSendGridClientInterface
2020
/** @var string SendGrid version */
2121
public $version = self::VERSION;
2222

23+
/** @var allowedRegionsHostMap regions specific hosts */
24+
public $allowedRegionsHostMap = [
25+
"eu" => "https://api.eu.sendgrid.com",
26+
"global" => "https://api.sendgrid.com",
27+
];
28+
2329
/**
2430
* Set up the HTTP Client.
2531
*
@@ -62,4 +68,23 @@ public function send(Mail $email)
6268
{
6369
return $this->client->mail()->send()->post($email);
6470
}
71+
72+
/*
73+
* Client libraries contain setters for specifying region/edge.
74+
* This allows support global and eu regions only. This set will likely expand in the future.
75+
* Global should be the default
76+
* Global region means the message should be sent through:
77+
* HTTP: api.sendgrid.com
78+
* EU region means the message should be sent through:
79+
* HTTP: api.eu.sendgrid.com
80+
*/
81+
public function setDataResidency($region): void
82+
{
83+
if (array_key_exists($region, $this->allowedRegionsHostMap)) {
84+
$this->client->setHost($this->allowedRegionsHostMap[$region]);
85+
} else {
86+
throw new InvalidArgumentException("region can only be \"eu\" or \"global\"");
87+
}
88+
}
89+
6590
}

test/unit/DataResidencyTest.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
/**
3+
* This file tests email address encoding.
4+
*/
5+
6+
namespace SendGrid\Tests\Unit;
7+
8+
use InvalidArgumentException;
9+
use PHPUnit\Framework\TestCase;
10+
11+
12+
/**
13+
* This class tests Data residency
14+
*
15+
* @package SendGrid\Tests
16+
*/
17+
class DataResidencyTest extends TestCase
18+
{
19+
public function testSetResidencyEu()
20+
{
21+
$sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY'));
22+
$sendgrid->setDataResidency("eu");
23+
self::assertEquals("https://api.eu.sendgrid.com", $sendgrid->client->getHost());
24+
}
25+
26+
public function testSetResidencyGlobal()
27+
{
28+
$sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY'));
29+
$sendgrid->setDataResidency("global");
30+
self::assertEquals("https://api.sendgrid.com", $sendgrid->client->getHost());
31+
}
32+
33+
public function testSetResidencyOverrideHost()
34+
{
35+
$sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY'));
36+
$sendgrid->client->setHost("https://test.api.com");
37+
$sendgrid->setDataResidency("eu");
38+
self::assertEquals("https://api.eu.sendgrid.com", $sendgrid->client->getHost());
39+
}
40+
41+
public function testSetResidencyOverrideDataResidency()
42+
{
43+
$sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY'));
44+
$sendgrid->setDataResidency("eu");
45+
$sendgrid->client->setHost("https://test.api.com");
46+
self::assertEquals("https://test.api.com", $sendgrid->client->getHost());
47+
}
48+
49+
public function testSetResidencyIncorrectRegion()
50+
{
51+
$this->expectException(InvalidArgumentException::class);
52+
$this->expectExceptionMessage("region can only be \"eu\" or \"global\"");
53+
54+
$sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY'));
55+
$sendgrid->setDataResidency("foo");
56+
}
57+
58+
public function testSetResidencyNullRegion()
59+
{
60+
$this->expectException(InvalidArgumentException::class);
61+
$this->expectExceptionMessage("region can only be \"eu\" or \"global\"");
62+
63+
$sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY'));
64+
$sendgrid->setDataResidency("");
65+
}
66+
67+
public function testSetResidencyDefaultRegion()
68+
{
69+
$sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY'));
70+
self::assertEquals("https://api.sendgrid.com", $sendgrid->client->getHost());
71+
}
72+
}

0 commit comments

Comments
 (0)