Skip to content

Commit

Permalink
fix: use POST to fetch (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
bgiori authored Jul 14, 2021
1 parent b742b5e commit 1ebf601
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 84 deletions.
3 changes: 1 addition & 2 deletions packages/node/src/amplitude.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ExperimentUser } from './types/user';
import { base64Decode } from './util/encode';

/**
* This class provides utility functions for parsing and handling identity
Expand Down Expand Up @@ -28,7 +27,7 @@ export class AmplitudeCookie {
let user_id = undefined;
if (values[1]) {
try {
user_id = base64Decode(values[1]);
user_id = Buffer.from(values[1], 'base64').toString('utf-8');
} catch (e) {
user_id = undefined;
}
Expand Down
16 changes: 11 additions & 5 deletions packages/node/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { FetchHttpClient } from './transport/http';
import { HttpClient } from './types/transport';
import { ExperimentUser } from './types/user';
import { Variant, Variants } from './types/variant';
import { urlSafeBase64Encode } from './util/encode';
import { performance } from './util/performance';
import { sleep } from './util/time';

Expand Down Expand Up @@ -75,16 +74,23 @@ export class ExperimentClient {
): Promise<Variants> {
const start = performance.now();
const userContext = this.addContext(user || {});
const encodedContext = urlSafeBase64Encode(JSON.stringify(userContext));
const endpoint = `${this.config.serverUrl}/sdk/vardata/${encodedContext}`;
const endpoint = `${this.config.serverUrl}/sdk/vardata`;
const headers = {
Authorization: `Api-Key ${this.apiKey}`,
};
const body = JSON.stringify(user);
// CDN can only cache requests where the body is < 8KB
if (body.length > 8000) {
console.warn(
`[Experiment] encoded user object length ${body.length} cannot be cached by CDN; must be < 8KB`,
);
}
this.debug('[Experiment] Fetch variants for user: ', userContext);
const response = await this.httpClient.request(
endpoint,
'GET',
'POST',
headers,
null,
body,
timeoutMillis,
);
if (response.status !== 200) {
Expand Down
13 changes: 4 additions & 9 deletions packages/node/src/transport/http.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import http from 'http';
import https from 'https';
import querystring, { ParsedUrlQueryInput } from 'querystring';
import url from 'url';

import { SimpleResponse, HttpClient } from '../types/transport';
Expand All @@ -16,19 +15,15 @@ const request: HttpClient['request'] = (
requestUrl: string,
method: string,
headers: Record<string, string>,
data?: Record<string, string>,
data: string,
timeoutMillis?: number,
): Promise<SimpleResponse> => {
const urlParams = url.parse(requestUrl);
if (method === 'GET' && data) {
urlParams.path = `${urlParams.path}?${querystring.encode(
data as ParsedUrlQueryInput,
)}`;
}
const options = {
...urlParams,
method,
headers,
method: method,
headers: headers,
body: data,
// Adds timeout to the socket connection, not the response.
timeout: timeoutMillis,
};
Expand Down
2 changes: 1 addition & 1 deletion packages/node/src/types/transport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface HttpClient {
requestUrl: string,
method: string,
headers: Record<string, string>,
data?: Record<string, string>,
body: string,
timeoutMillis?: number,
): Promise<SimpleResponse>;
}
30 changes: 0 additions & 30 deletions packages/node/src/util/encode.ts

This file was deleted.

34 changes: 34 additions & 0 deletions packages/node/test/client.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ExperimentClient } from 'src/client';
import { ExperimentUser } from 'src/types/user';

const API_KEY = 'client-DvWljIjiiuqLbyjqdvBaLFfEBrAvGuA3';

const testUser: ExperimentUser = { user_id: 'test_user' };

const testClient: ExperimentClient = new ExperimentClient(API_KEY, {});

const testTimeoutNoRetriesClient = new ExperimentClient(API_KEY, {
fetchRetries: 0,
fetchTimeoutMillis: 1,
});

const testTimeoutRetrySuccessClient = new ExperimentClient(API_KEY, {
fetchTimeoutMillis: 1,
});

test('ExperimentClient.fetch, success', async () => {
const variants = await testClient.fetch(testUser);
const variant = variants['sdk-ci-test'];
expect(variant).toEqual({ value: 'on', payload: 'payload' });
});

test('ExperimentClient.fetch, no retries, timeout failure', async () => {
const variants = await testTimeoutNoRetriesClient.fetch(testUser);
expect(variants).toEqual({});
});

test('ExperimentClient.fetch, no retries, timeout failure', async () => {
const variants = await testTimeoutRetrySuccessClient.fetch(testUser);
const variant = variants['sdk-ci-test'];
expect(variant).toEqual({ value: 'on', payload: 'payload' });
});
37 changes: 0 additions & 37 deletions packages/node/test/util/encode.test.ts

This file was deleted.

0 comments on commit 1ebf601

Please sign in to comment.