api_core: Add routing header (#4336)

* api_core: Add routing header

* Fix linting

* Review fixes

* More review fixes

* Documentation fixes
diff --git a/google/api_core/gapic_v1/__init__.py b/google/api_core/gapic_v1/__init__.py
index fbf674b..e26a499 100644
--- a/google/api_core/gapic_v1/__init__.py
+++ b/google/api_core/gapic_v1/__init__.py
@@ -14,8 +14,10 @@
 
 from google.api_core.gapic_v1 import config
 from google.api_core.gapic_v1 import method
+from google.api_core.gapic_v1 import routing_header
 
 __all__ = [
     'config',
     'method',
+    'routing_header',
 ]
diff --git a/google/api_core/gapic_v1/routing_header.py b/google/api_core/gapic_v1/routing_header.py
new file mode 100644
index 0000000..a9626ee
--- /dev/null
+++ b/google/api_core/gapic_v1/routing_header.py
@@ -0,0 +1,53 @@
+# Copyright 2017 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Helpers for constructing routing headers.
+
+These headers are used by Google infrastructure to determine how to route
+requests, especially for services that are regional.
+
+Generally, these headers are specified as gRPC metadata.
+"""
+
+from six.moves.urllib.parse import urlencode
+
+ROUTING_METADATA_KEY = 'x-goog-header-params'
+
+
+def to_routing_header(params):
+    """Returns a routing header string for the given request parameters.
+
+    Args:
+        params (Mapping[str, Any]): A dictionary containing the request
+            parameters used for routing.
+
+    Returns:
+        str: The routing header string.
+    """
+    return urlencode(params)
+
+
+def to_grpc_metadata(params):
+    """Returns the gRPC metadata containing the routing headers for the given
+    request parameters.
+
+    Args:
+        params (Mapping[str, Any]): A dictionary containing the request
+            parameters used for routing.
+
+    Returns:
+        Tuple(str, str): The gRPC metadata containing the routing header key
+            and value.
+    """
+    return (ROUTING_METADATA_KEY, to_routing_header(params))
diff --git a/tests/unit/gapic/test_routing_header.py b/tests/unit/gapic/test_routing_header.py
new file mode 100644
index 0000000..d3a4bc3
--- /dev/null
+++ b/tests/unit/gapic/test_routing_header.py
@@ -0,0 +1,29 @@
+# Copyright 2017 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+from google.api_core.gapic_v1 import routing_header
+
+
+def test_to_routing_header():
+    params = [('name', 'meep'), ('book.read', '1')]
+    value = routing_header.to_routing_header(params)
+    assert value == "name=meep&book.read=1"
+
+
+def test_to_grpc_metadata():
+    params = [('name', 'meep'), ('book.read', '1')]
+    metadata = routing_header.to_grpc_metadata(params)
+    assert metadata == (
+        routing_header.ROUTING_METADATA_KEY, "name=meep&book.read=1")