Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/api/routes/key-value-stores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,12 @@ export function mountKeyValueStoreOperations(router: Router, basePath: string, r
const store = await openKeyValueStore(record.id);
const contentType = req.header('content-type') ?? 'application/octet-stream';
const body = Buffer.isBuffer(req.body) ? req.body : Buffer.alloc(0);
await store.setValue(req.params.recordKey as string, body, { contentType });
const recordKey = req.params.recordKey as string;
// A record is created once and overwritten afterwards; the status tells the client which.
const existed = (await store.getRecord(recordKey)) !== null;
await store.setValue(recordKey, body, { contentType });
await touchStorage(record.id);
res.status(201).end();
res.status(existed ? 200 : 201).end();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important: the real platform answers 201 to every record store, overwrite or not (apify-core src/api/src/routes/key_value_stores/record.ts:168, res.status(201).json({})), and requirements/ documents no difference, so an overwrite answering 200 makes the emulator diverge from the platform in a way clients can observe.

});
router.put(`${basePath}/records/:recordKey`, setRecord);
// The spec's "Store record (POST)": an alias of the PUT, for clients that cannot send PUT.
Expand Down
4 changes: 2 additions & 2 deletions test/integration/key-value-stores.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ describe('key-value-stores API (via real apify-client)', () => {
expect(posted.status).toBe(201);
expect((await store.getRecord('OUTPUT'))?.value).toEqual({ via: 'post' });

// Overwrites like PUT does, keeping the content type it was sent with.
// Overwrites like PUT does, keeping the content type it was sent with; an overwrite is a 200.
const overwritten = await fetch(`${server.baseUrl}/v2/key-value-stores/${id}/records/OUTPUT`, {
method: 'POST',
headers: { Authorization: `Bearer ${server.token}`, 'Content-Type': 'text/plain' },
body: 'plain',
});
expect(overwritten.status).toBe(201);
expect(overwritten.status).toBe(200);
const record = await store.getRecord('OUTPUT');
expect(record?.value).toBe('plain');
expect(record?.contentType).toMatch(/^text\/plain/);
Expand Down
Loading