Chapter 1. Introduction to advanced operation of 3scale APIcast API gateway

The introduction to advanced operation of 3scale APIcast will help you to adjust the configuration of access to your API.

1.1. Public base URL for calls to 3scale APIs

The Public Base URL is the URL that your API consumers use to make requests to your API product, which is exposed publicly with 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 of the environments provided (staging and production) on a domain name you are managing. This URL should be different from the one for 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.

Note

The Public Base URL that you specify must use a port that is available in your OpenShift cluster. By default, the OpenShift router listens for connections only on the standard HTTP and HTTPS ports (80 and 443). If you want users to connect to your API over some other port, work with your OpenShift administrator to enable the port.

APIcast accepts calls to only the hostname specified in the Public Base URL. For example, if you specify https://echo-api.3scale.net:443 as the Public Base URL, the correct call would be:

curl "https://echo-api.3scale.net:443/hello?user_key=you_user_key"

In case you do not have a public domain for your API, you can use the APIcast IP address in the requests, but you still need to specify a value in the Public Base URL field even if the domain is not real. 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 a local machine, you can specify "localhost" as the domain, so the Public Base URL would look like http://localhost:80, and then you can make requests like this:

curl "http://localhost:80/hello?user_key=your_user_key"

If you have multiple API products, set the Public Base URL appropriately for each product. APIcast routes the requests based on the hostname.

1.2. How APIcast applies mapping rules for capturing usage of 3scale APIs

Based on the requests to your API, mapping rules define the metrics or designate the methods for which you want to capture API usage. The following is an example of a mapping rule:

Mapping Rules

This rule means that any GET requests that start with / increment the metric hits by 1. This rule matches any request to your API. While this is a valid mapping rule, it is too generic and often leads to double counts if you add more specific mapping rules.

The following mapping rules for the Echo API show more specific examples:

Hello World Mapping Rules

Mapping rules work at the API product and API backend levels.

  • Mapping rules at the product level.

    • The mapping rule takes precedence. This means that the product mapping rule is the first one to be evaluated.
    • The mapping rule is always evaluated, independent of which backend receives the redirected traffic.
  • Mapping rules at the backend level.

    • When you add mapping rules to a backend, these are added to all the products bundling said backend.
    • The mapping rule is evaluated after the mapping rules defined at the product level.
    • The mapping rule is evaluated only if the traffic is redirected to the same backend the mapping rule belongs to.
    • The path of the backend for a product is automatically prepended to each mapping rule of the backend bundled to said product.

Example of mapping rules with products and backends

The following example shows mapping rules for a product with one backend.

Now consider an additional product called Tools For Devs using the same Echo API backend.

Matching of mapping rules

3scale applies mapping rules based on prefixes. The notation follows the OpenAPI and ActiveDocs specifications:

  • A mapping rule must start with a forward slash (/).
  • Perform a match on the path over a literal string, which is a URL, for example, /hello.

    • The mapping rule, once you have saved it, will cause requests to the URL string you have set and invoke metrics or methods you have defined around each mapping rule.
  • 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, or PUT method: From the body.
  • Mapping rules can contain named wildcards, for example, /{word}. This rule matches anything in the placeholder {word}, which makes requests such as /morning match the mapping rule. Wildcards can appear between slashes or between a slash and a dot. Parameters can also include wildcards.
  • By default, all mapping rules are evaluated from first to last, according to the sort order you specified. If you add a rule /v1, it matches 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 matches only /v1/word requests, and does 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.

Mapping rules workflow

Mapping rules have the following workflow:

  • You can define a new mapping rule at any time. See Defining mapping rules.
  • Mapping rules are 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 promote the changes in Integration > Configuration.

Stop other mapping rules

After processing one or more mapping rules, to stop processing other mapping rules, select Last? when creating a new mapping rule. For example, suppose 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, after matching the rule, APIcast stops processing the remaining mapping rules and stops incrementing their metrics.

1.3. How APIcast handles APIs that have custom requirements

There are special cases that require custom APIcast configuration so that API consumers can successfully call the API.

Host header

This option is only needed for those API products that reject traffic unless the Host header matches the expected one. In these cases, having a gateway in front of your API product causes problems because the Host is the one of the gateway, for example, xxx-yyy.staging.apicast.io.

To avoid this issue, you can define the host your API product expects in the Host Header field in the Authentication Settings: [Your_product_name] > Integration > Settings

The result is that the hosted APIcast instance rewrites the host specification in the request call.

Host Rewrite

Protecting your API backend

After you have APIcast working in production, you might want to restrict direct access to your API product to only those calls that specify a secret token that you specify. Do this by setting the APIcast Secret Token. See Advanced APIcast configuration for information on how to set it up.

Using APIcast with private APIs

With APIcast, it is possible to protect the APIs that 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 product 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. However, doing this means that you cannot take advantage of the staging environment. Test calls will not be successful because the staging APIcast instance is hosted by 3scale, which does not have access to your private API backend. After you deploy APIcast in your production environment, if the configuration is correct, APIcast works as expected.

1.4. Configuring APIcast to use OpenTracing

OpenTracing is an API specification and method used to profile and monitor microservices. APIcast version 3.3 and later includes OpenTracing libraries and the Jaeger Tracer library.

Prerequisites

  • Each external request must have a unique request ID attached. This is usually in an HTTP header.
  • Each service must forward the request ID to other services.
  • Each service must output the request ID in the logs.
  • Each service must record additional information, such as the start and end time of the request.
  • Logs must be aggregated, and provide a way to parse them via HTTP request ID.

Procedure

  1. Ensure the OPENTRACING_TRACER environment variable is set to jaeger. If this is empty, OpenTracing is disabled.
  2. Set the OPENTRACING_CONFIG environment variable to specify the default configuration file of your tracer. See the following example jaeger.example.json file.
  3. Optional: Set the OPENTRACING_HEADER_FORWARD environment variable according to your OpenTracing configuration.

Verification

To test if the integration is properly working, check whether traces are reported in the Jaeger tracing interface.

1.5. Installing Jaeger on your OpenShift instance

3scale API providers can use OpenTracing with Jaeger to trace and troubleshoot calls to an API. To do this, install Jaeger on the OpenShift instance on which 3scale is running.

Warning

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.

Procedure

  1. Install the Jaeger all-in-one template 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 -
  2. 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
        }
     }
    • A sampler constant of 1 indicates that you want to sample all requests.
    • The location and queue size of the reporter are required.
    • Under headers, the TraceContextHeaderName entry is required to track requests
  3. Create a ConfigMap from your Jaeger configuration file and mount it into APIcast:

    oc create configmap jaeger-config --from-file=jaeger_config.json
    oc set volumes dc/apicast --add -m /tmp/jaeger/ --configmap-name jaeger-config
  4. Enable OpenTracing and Jaeger with the configuration you just added:

    oc set env deploymentConfig/apicast OPENTRACING_TRACER=jaeger OPENTRACING_CONFIG=/tmp/jaeger/jaeger_config.json
  5. Find the URL that the Jaeger interface is running on:

    oc get route
    (…) jaeger-query-myproject.127.0.0.1.nip.io
  6. Open the Jaeger interface from the previous step, which shows data being populated from Openshift Health checks.
  7. 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, see Using OpenTracing with Jaeger to collect Application Metrics in Kubernetes.