Skip to content

Commit

Permalink
feat: Add support for meta through post requests
Browse files Browse the repository at this point in the history
Fixes #24
  • Loading branch information
relekang committed Jun 24, 2017
1 parent ba3a797 commit 915642f
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 14 deletions.
18 changes: 17 additions & 1 deletion packages/micro-analytics-cli/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,28 @@ To track a view of `x`, simply send a request to `/x`. This is how you'd track p
</script>
```

If you send a `GET` request, the request will increment the views and return the total views for the id. (in this case "x") If you send a `POST` request, the views will increment but you don't get the total views back.
If you send a `GET` or `POST` request, the request will increment the views and return the total views for the id (in this case "x").

#### `GET` the views without incrementing

If you just want to get the views for an id and don't want to increment the views during a `GET` request, set `inc` to `false` in your query parameter. (`/x?inc=false`)

#### `POST` to add metadata

You can add more metadata to the view by posting a JSON payload with the field `meta`. Everything in that meta field will be set on meta in the view object. You can read
the data out with the `all` option, see below for more info. Example request that will post the browser useragent string:

```html
<script>
fetch('servicedomain.com' + window.location.pathname, {
method: "POST",
credentials: "include",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({meta: { browser: navigator.userAgent }}),
})
</script>
```

### Getting all views

If you want to get all views for all ids, set the `all` query parameter to `true` on a root request. (i.e. `/?all=true`) If you pass the `all` parameter to an id, all ids starting with that pathname will be included. E.g. `/x?all=true` will match views for `/x`, `/xyz` but not `/y`.
Expand Down
29 changes: 19 additions & 10 deletions packages/micro-analytics-cli/src/handler.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const url = require('url');
const { send, createError, sendError } = require('micro');
const { json, send, createError, sendError } = require('micro');

const db = require('./db');
const healthcheckHandler = require('./healthcheck');
Expand All @@ -24,6 +24,14 @@ function realtimeHandler(req, res) {
}
}

async function readMeta(req) {
try {
return (await json(req)).meta;
} catch (error) {
return null;
}
}

async function analyticsHandler(req, res) {
const { pathname, query } = url.parse(req.url, /* parseQueryString */ true);
res.setHeader('Access-Control-Allow-Origin', '*');
Expand Down Expand Up @@ -55,17 +63,18 @@ async function analyticsHandler(req, res) {
const shouldIncrement = String(query.inc) !== 'false';
try {
const currentViews = (await db.has(pathname)) ? (await db.get(pathname)).views.length : 0;
// Add a view and send the total views back to the client
if (shouldIncrement) {
await pushView(pathname, { time: Date.now() });
const meta = await readMeta(req);

const data = { time: Date.now() };
if (meta) {
data.meta = meta;
}
if (req.method === 'GET') {
send(res, 200, {
views: shouldIncrement ? currentViews + 1 : currentViews,
});
} else {
send(res, 200);

if (shouldIncrement) {
await pushView(pathname, data);
}

send(res, 200, { views: shouldIncrement ? currentViews + 1 : currentViews });
} catch (err) {
console.log(err);
throw createError(500, 'Internal server error.');
Expand Down
17 changes: 14 additions & 3 deletions packages/micro-analytics-cli/tests/items.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,20 @@ describe('single', () => {
expect(body.views).toEqual(1);
});

it('should not return anything for a POST request', async () => {
const body = await request.post(`${server.url}/existant`);
expect(body).toEqual('');
describe('POST', () => {
it('should increment the views of an existant path', async () => {
await request.post(`${server.url}/existant`);
const body = JSON.parse(await request(`${server.url}/existant`));
expect(body.views).toEqual(2);
});

it('should increment the views of an existant path and store metadata', async () => {
await request.post(`${server.url}/existant`, {
body: JSON.stringify({ meta: { browser: 'IE 6' } }),
});
const [data] = (await db.get('/existant')).views;
expect(data).toMatchObject({ meta: { browser: 'IE 6' } });
});
});
});

Expand Down

0 comments on commit 915642f

Please sign in to comment.