//
// 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.
//
=== Request examples

==== Retrieving your first context

You can retrieve a context using curl like this :

[source]
----
curl http://localhost:8181/cxs/context.js?sessionId=1234
----

This will retrieve a JavaScript script that contains a `cxs` object that contains the context with the current user
profile, segments, scores as well as functions that makes it easier to perform further requests (such as collecting
events using the cxs.collectEvents() function).

==== Retrieving a context as a JSON object.

If you prefer to retrieve a pure JSON object, you can simply use a request formed like this:

[source]
----
curl http://localhost:8181/cxs/context.json?sessionId=1234
----

==== Accessing profile properties in a context

By default, in order to optimize the amount of data sent over the network, Apache Unomi will not send the content of
the profile or session properties. If you need this data, you must send a JSON object to configure the resulting output
of the context.js(on) servlet.

Here is an example that will retrieve all the session and profile properties.

[source]
----
curl -X POST http://localhost:8181/cxs/context.json?sessionId=1234 \
-H "Content-Type: application/json" \
-d @- <<'EOF'
{
    "source": {
        "itemId":"homepage",
        "itemType":"page",
        "scope":"example"
    },
    "requiredProfileProperties":["*"],
    "requiredSessionProperties":["*"],
    "requireSegments":true
}
EOF
----

The `requiredProfileProperties` and `requiredSessionProperties` are properties that take an array of property names
that should be retrieved. In this case we use the wildcard character '*' to say we want to retrieve all the available
properties. The structure of the JSON object that you should send is a JSON-serialized version of the http://unomi.apache.org/unomi-api/apidocs/org/apache/unomi/api/ContextRequest.html[ContextRequest]
Java class.

==== Sending events using the context servlet

At the same time as you are retrieving the context, you can also directly send events in the ContextRequest object as
illustrated in the following example:

[source]
----
curl -X POST http://localhost:8181/cxs/context.json?sessionId=1234 \
-H "Content-Type: application/json" \
-d @- <<'EOF'
{
    "source":{
        "itemId":"homepage",
        "itemType":"page",
        "scope":"example"
    },
    "events":[
        {
            "eventType":"view",
            "scope": "example",
            "source":{
                "itemType": "site",
                "scope":"example",
                "itemId": "mysite"
            },
            "target":{
                "itemType":"page",
                "scope":"example",
                "itemId":"homepage",
                "properties":{
                    "pageInfo":{
                        "referringURL":""
                    }
                }
            }
        }
    ]
}
EOF
----

Upon received events, Apache Unomi will execute all the rules that match the current context, and return an updated context.
This way of sending events is usually used upon first loading of a page. If you want to send events after the page has
finished loading you could either do a second call and get an updating context, or if you don't need the context and want
to send events in a network optimal way you can use the eventcollector servlet (see below).

==== Sending events using the eventcollector servlet

If you only need to send events without retrieving a context, you should use the eventcollector servlet that is optimized
respond quickly and minimize network traffic. Here is an example of using this servlet:

[source]
----
curl -X POST http://localhost:8181/cxs/eventcollector \
-H "Content-Type: application/json" \
-d @- <<'EOF'
{
    "sessionId" : "1234",
    "events":[
        {
            "eventType":"view",
            "scope": "example",
            "source":{
                "itemType": "site",
                "scope":"example",
                "itemId": "mysite"
            },
            "target":{
                "itemType":"page",
                "scope":"example",
                "itemId":"homepage",
                "properties":{
                    "pageInfo":{
                        "referringURL":""
                    }
                }
            }
        }
    ]
}
EOF
----

Note that the eventcollector executes the rules but does not return a context. If is generally used after a page is loaded
to send additional events.

==== Where to go from here

* You can find more <<Useful Apache Unomi URLs,useful Apache Unomi URLs>> that can be used in the same way as the above examples.
* You may want to know integrate the provided <<Web Tracker,web tracker>> into your web site.
* Read the <<Twitter sample,Twitter sample>> documentation that contains a detailed example of how to integrate with Apache Unomi.
