Chapter 1. Operating APIcast
This section describes the concepts to consider when working with advanced APIcast configurations.
1.1. Mapping rules
Mapping rules define the metrics or methods that you want to report depending on the requests to your API. The following is an example mapping rule:
This rule means that any GET
requests that start with /
will increment the metric hits
by 1. This rule will match any request to your API. But most likely, you will change this rule because it is too generic.
The following rules for the Echo API show more specific examples:
1.1.1. Matching of mapping rules
The matching of mapping rules is performed by prefix and can be arbitrarily complex (the notation follows OpenAPI and ActiveDocs specifications):
-
A mapping rule must start with a forward slash (
/
). -
You can perform a match on the path over a literal string (for example,
/hello
). Mapping rules can include parameters on the query string or in the body (for example,
/{word}?value={value}
). APIcast fetches the parameters in the following ways:-
GET
method: From the query string. -
POST
,DELETE
, orPUT
method: From the body.
-
-
Mapping rules can contain named wildcards (for example,
/{word}
). This rule will match anything in the placeholder{word}
, making requests like/morning
match the rule. Wildcards can appear between slashes or between slash and dot. Parameters can also include wildcards. -
By default, all mapping rules are evaluated from first to last, according to the sort you specified. If you add a rule
/v1
, it will be matched for requests whose paths start with/v1
(for example,/v1/word
or/v1/sentence
). -
You can add a dollar sign (
$
) to the end of a pattern to specify exact matching. For example,/v1/word$
will only match/v1/word
requests, and will not match/v1/word/hello
requests. For exact matching, you must also ensure that the default mapping rule that matches everything (/
) has been disabled. - More than one mapping rule can match the request path, but if none matches, the request is discarded with an HTTP 404 status code.
1.1.2. Mapping rules workflow
Mapping rules have the following workflow:
- You can define a new mapping rule (see Add mapping rules).
- Mapping rules will be grayed out on the next reload to prevent accidental modifications.
- To edit an existing mapping rule, you must enable it first by clicking the pencil icon on the right.
- To delete a rule, click the trash icon.
- All modifications and deletions are saved when you click Update & Test Staging Configuration.
Add mapping rules
To add a new mapping rule, perform the following steps:
- Click Add Mapping Rule.
Specify the following settings:
-
Verb: The HTTP request verb (
GET
,POST
,DELETE
, orPUT
). -
Pattern: The pattern to match (for example,
/hello
). -
+: The metric increment number (for example,
1
). -
Metric (or method): The metric or method name (for example,
gethello
).
-
Verb: The HTTP request verb (
- Click Update & Test Staging Configuration to apply the changes.
Stop other mapping rules
To stop processing other mapping rules, you can select Last?. For example, if you have the following mapping rules defined in API Integration Settings and you have different metrics associated with each rule:
(get) /path/to/example/search (get) /path/to/example/{id}
When calling with (get) /path/to/example/search
, APIcast will stop processing the remaining mapping rules and incrementing their metrics after the rule is matched.
Sort mapping rules
To sort mapping rules, you can drag and drop them using the green arrows for each mapping rule next to the Last? setting. The specified sort is saved in the database and is kept in the proxy configuration after you click Update & test in Staging Environment.
For more configuration options, see APIcast advanced configuration.
1.2. Host header
This option is only needed for those API backends that reject traffic unless the Host
header matches the expected one. In these cases, having a gateway in front of your API backend will cause problems since the Host
will be the one of the gateway, e.g. xxx-yyy.staging.apicast.io
To avoid this issue you can define the host your API backend expects in the Host Header field in the Authentication Settings, and the hosted APIcast instance will rewrite the host.
1.3. Production deployment
Once you have configured your API integration and verified it is working in the Staging environment, you can go ahead with one of the APIcast production deployments.
At the bottom of the Integration page you will find the Production section. You will find two fields here: the Private Base URL, which will be the same as you configured in the Staging section, and the Public Base URL.
1.4. Public Base URL
The Public Base URL is the URL, which your developers will use to make requests to your API, protected by 3scale. This will be the URL of your APIcast instance.
If you are using one of the Self-managed deployment options, you can choose your own Public Base URL for each one of the environments provided (staging and production), on a domain name you are managing. Note that this URL should be different from the one of your API backend, and could be something like https://api.yourdomain.com:443
, where yourdomain.com
is the domain that belongs to you. After setting the Public Base URL make sure you save the changes and, if necessary, promote the changes in staging to production.
Please note that APIcast will only accept calls to the hostname which is specified in the Public Base URL. For example, for the Echo API example used above, if we specify https://echo-api.3scale.net:443
as the Public Base URL, the correct call would be be:
curl "https://echo-api.3scale.net:443/hello?user_key=YOUR_USER_KEY"
In case you don’t yet have a public domain for your API, you can also use the APIcast IP in the requests, but you still need to specify a value in the Public Base URL field (even if the domain is not real), and in this case make sure you provide the host in the Host header, for example:
curl "http://192.0.2.12:80/hello?user_key=YOUR_USER_KEY" -H "Host: echo-api.3scale.net"
If you are deploying on local machine, you can also just use "localhost" as the domain, so the Public Base URL will look like http://localhost:80
, and then you can make requests like this:
curl "http://localhost:80/hello?user_key=YOUR_USER_KEY"
In case you have multiple API services, you will need to set this Public Base URL appropriately for each service. APIcast will route the requests based on the hostname.
1.5. Protecting your API backend
Once you have APIcast working in production, you might want to restrict direct access to your API backend without credentials. The easiest way to do this is by using the Secret Token set by APIcast. Please refer to the Advanced APIcast configuration for information on how to set it up.
1.6. Using APIcast with private APIs
With APIcast it is possible to protect the APIs which are not publicly accessible on the Internet. The requirements that must be met are:
- Self-managed APIcast must be used as the deployment option.
- APIcast needs to be accessible from the public internet and be able to make outbound calls to the 3scale Service Management API.
- The API backend should be accessible by APIcast.
In this case you can set your internal domain name or the IP address of your API in the Private Base URL field and follow the rest of the steps as usual. Note, however, that you will not be able to take advantage of the Staging environment, and the test calls will not be successful, as the Staging APIcast instance is hosted by 3scale and will not have access to your private API backend). But once you deploy APIcast in your production environment, if the configuration is correct, APIcast will work as expected.
1.7. Configuring APIcast with OpenTracing
OpenTracing is an API specification and method used to profile and monitor microservices. From version 3.3 onwards, APIcast includes OpenTracing Libraries and the Jaeger Tracer library.
1.7.1. Prerequisites
To add distributed tracing to your APIcast deployment, you need to ensure the following prerequisites:
- Each external request should have a unique request ID attached, usually via a HTTP header.
- Each service should forward the request ID to other services.
- Each service should output the request ID in the logs.
- Each service should record additional information, like start and end time of the request.
- Logs need to be aggregated, and provide a way to parse via HTTP request ID.
1.7.2. Procedure
To configure OpenTracing, use the following environment variables:
- OPENTRACING_TRACER: To define which tracer implementation to use. Currently, only Jaeger is available.
- OPENTRACING_CONFIG: To specify the default configuration file of your tracer. You can see an example here.
- OPENTRACING_HEADER_FORWARD: Optional. You can set this environment variable according to your OpenTracing configuration.
For more information about these variables, refer to APIcast environment variables.
To test if the integration is properly working, you need to check if traces are reported in the Jaeger tracing interface.
1.7.3. Additional information
The OpenTracing and Jaeger integration are available in the upstream project: https://github.com/3scale/apicast
1.7.4. Installing Jaeger on your OpenShift instance
This section provides information about the installation of Jaeger on the OpenShift instance you are running.
Jaeger is a third-party component, which 3scale does not provide support for, with the exception of uses with APIcast. The following instructions are provided as a reference example only, and are not suitable for production use.
Install the Jaeger all-in-one in the current namespace:
oc process -f https://raw.githubusercontent.com/jaegertracing/jaeger-openshift/master/all-in-one/jaeger-all-in-one-template.yml | oc create -f -
Create a Jaeger configuration file
jaeger_config.json
and add the following:{ "service_name": "apicast", "disabled": false, "sampler": { "type": "const", "param": 1 }, "reporter": { "queueSize": 100, "bufferFlushInterval": 10, "logSpans": false, "localAgentHostPort": "jaeger-agent:6831" }, "headers": { "jaegerDebugHeader": "debug-id", "jaegerBaggageHeader": "baggage", "TraceContextHeaderName": "uber-trace-id", "traceBaggageHeaderPrefix": "testctx-" }, "baggage_restrictions": { "denyBaggageOnInitializationFailure": false, "hostPort": "127.0.0.1:5778", "refreshInterval": 60 } }
-
set a
sampler
constant of 1 to sample all requests -
set the location and queue size of the
reporter
-
set
headers
, includingTraceContextHeaderName
which we will use to track requests
-
set a
Create a ConfigMap from our Jaeger configuration file and mount it into APIcast:
oc create configmap jaeger-config --from-file=jaeger_config.json oc volume dc/apicast --add -m /tmp/jaeger/ --configmap-name jaeger-config
Enable OpenTracing and Jaeger with the configuration we have just added:
oc set env deploymentConfig/apicast OPENTRACING_TRACER=jaeger OPENTRACING_CONFIG=/tmp/jaeger/jaeger_config.json
Find the URL the Jaeger interface is running on:
oc get route (…) jaeger-query-myproject.127.0.0.1.nip.io
- Open the Jaeger interface from the previous step, which shows data being populated from Openshift Health checks.
- The final step is to add OpenTracing and Jaeger support to your backend APIs so that you can see the complete request trace. This varies in each back end, depending on the frameworks and languages used. As a reference example, you can see Using OpenTracing with Jaeger to collect Application Metrics in Kubernetes.
For more information on configuring Jaeger, see: