summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Matthew Phillips <matthew@skypack.dev> 2022-05-04 14:55:37 -0400
committerGravatar GitHub <noreply@github.com> 2022-05-04 14:55:37 -0400
commit6643a3931d45e63363599bb0cf7b2b2951266cfb (patch)
treeed58c3531fb0da64ac6f94ab3dac2fb6117dda7a
parentd825d376f8a2548a25accee0dfe71e03ecd83d7e (diff)
downloadastro-6643a3931d45e63363599bb0cf7b2b2951266cfb.tar.gz
astro-6643a3931d45e63363599bb0cf7b2b2951266cfb.tar.zst
astro-6643a3931d45e63363599bb0cf7b2b2951266cfb.zip
Conform to API route signature (#3272)
* Conform to API route signature * Rename to API route * Update ssr test * Update packages/astro/test/fixtures/ssr-dynamic/src/pages/api/products/[id].js Co-authored-by: Ben Holmes <hey@bholmes.dev> * Adds a changeset * Make PR review changes Co-authored-by: Ben Holmes <hey@bholmes.dev>
-rw-r--r--.changeset/fast-dolls-eat.md5
-rw-r--r--packages/astro/src/@types/astro.ts17
-rw-r--r--packages/astro/src/core/render/route-cache.ts1
-rw-r--r--packages/astro/src/runtime/server/index.ts42
-rw-r--r--packages/astro/test/api-routes.test.js44
-rw-r--r--packages/astro/test/fixtures/api-routes/src/pages/context/data/[param].json.js24
-rw-r--r--packages/astro/test/fixtures/api-routes/src/pages/old-api/onearg/[param].json.js23
-rw-r--r--packages/astro/test/fixtures/api-routes/src/pages/old-api/twoarg/[param].json.js24
-rw-r--r--packages/astro/test/fixtures/ssr-dynamic/src/pages/api/products/[id].js2
9 files changed, 179 insertions, 3 deletions
diff --git a/.changeset/fast-dolls-eat.md b/.changeset/fast-dolls-eat.md
new file mode 100644
index 000000000..3eda1c985
--- /dev/null
+++ b/.changeset/fast-dolls-eat.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Implements the Dynamic Route API RFC
diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts
index 2848760d2..805eeb407 100644
--- a/packages/astro/src/@types/astro.ts
+++ b/packages/astro/src/@types/astro.ts
@@ -856,12 +856,27 @@ export interface AstroAdapter {
args?: any;
}
+export interface APIContext {
+ params: Params;
+ request: Request;
+}
+
export interface EndpointOutput<Output extends Body = Body> {
body: Output;
}
+interface APIRoute {
+ (context: APIContext): EndpointOutput | Response;
+
+ /**
+ * @deprecated
+ * Use { context: APIRouteContext } object instead.
+ */
+ (params: Params, request: Request): EndpointOutput | Response;
+}
+
export interface EndpointHandler {
- [method: string]: (params: any, request: Request) => EndpointOutput | Response;
+ [method: string]: APIRoute;
}
export interface AstroRenderer {
diff --git a/packages/astro/src/core/render/route-cache.ts b/packages/astro/src/core/render/route-cache.ts
index b564a6ca6..762128555 100644
--- a/packages/astro/src/core/render/route-cache.ts
+++ b/packages/astro/src/core/render/route-cache.ts
@@ -52,6 +52,7 @@ export async function callGetStaticPaths({
const keyedStaticPaths = staticPaths as GetStaticPathsResultKeyed;
keyedStaticPaths.keyed = new Map<string, GetStaticPathsItem>();
+
for (const sp of keyedStaticPaths) {
const paramsKey = stringifyParams(sp.params);
keyedStaticPaths.keyed.set(paramsKey, sp);
diff --git a/packages/astro/src/runtime/server/index.ts b/packages/astro/src/runtime/server/index.ts
index c9df2e62b..dd278ae5a 100644
--- a/packages/astro/src/runtime/server/index.ts
+++ b/packages/astro/src/runtime/server/index.ts
@@ -1,4 +1,5 @@
import type {
+ APIContext,
AstroComponentMetadata,
AstroGlobalPartial,
EndpointHandler,
@@ -468,7 +469,46 @@ export async function renderEndpoint(mod: EndpointHandler, request: Request, par
`Endpoint handler not found! Expected an exported function for "${chosenMethod}"`
);
}
- return await handler.call(mod, params, request);
+
+ if(handler.length > 1) {
+ // eslint-disable-next-line no-console
+ console.warn(`
+API routes with 2 arguments have been deprecated. Instead they take a single argument in the form of:
+
+export function get({ params, request }) {
+ //...
+}
+
+Update your code to remove this warning.`)
+ }
+
+ const context = {
+ request,
+ params
+ };
+
+ const proxy = new Proxy(context, {
+ get(target, prop) {
+ if(prop in target) {
+ return Reflect.get(target, prop);
+ } else if(prop in params) {
+ // eslint-disable-next-line no-console
+ console.warn(`
+API routes no longer pass params as the first argument. Instead an object containing a params property is provided in the form of:
+
+export function get({ params }) {
+ // ...
+}
+
+Update your code to remove this warning.`);
+ return Reflect.get(params, prop);
+ } else {
+ return undefined;
+ }
+ }
+ }) as APIContext & Params;
+
+ return await handler.call(mod, proxy, request);
}
async function replaceHeadInjection(result: SSRResult, html: string): Promise<string> {
diff --git a/packages/astro/test/api-routes.test.js b/packages/astro/test/api-routes.test.js
new file mode 100644
index 000000000..d7d0c3d29
--- /dev/null
+++ b/packages/astro/test/api-routes.test.js
@@ -0,0 +1,44 @@
+import { expect } from 'chai';
+import * as cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
+
+describe('API routes', () => {
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({ root: './fixtures/api-routes/' });
+ await fixture.build();
+ });
+
+ describe('Deprecated API', () => {
+ it('two argument supported', async () => {
+ const one = JSON.parse(await fixture.readFile('/old-api/twoarg/one.json'));
+ expect(one).to.deep.equal({
+ param: 'one',
+ pathname: '/old-api/twoarg/one.json'
+ });
+ const two = JSON.parse(await fixture.readFile('/old-api/twoarg/two.json'));
+ expect(two).to.deep.equal({
+ param: 'two',
+ pathname: '/old-api/twoarg/two.json'
+ });
+ });
+
+ it('param first argument is supported', async () => {
+ const one = JSON.parse(await fixture.readFile('/old-api/onearg/one.json'));
+ expect(one).to.deep.equal({
+ param: 'one'
+ });
+ });
+ });
+
+ describe('1.0 API', () => {
+ it('Receives a context argument', async () => {
+ const one = JSON.parse(await fixture.readFile('/context/data/one.json'));
+ expect(one).to.deep.equal({
+ param: 'one',
+ pathname: '/context/data/one.json'
+ });
+ });
+ });
+});
diff --git a/packages/astro/test/fixtures/api-routes/src/pages/context/data/[param].json.js b/packages/astro/test/fixtures/api-routes/src/pages/context/data/[param].json.js
new file mode 100644
index 000000000..2ed42a5ec
--- /dev/null
+++ b/packages/astro/test/fixtures/api-routes/src/pages/context/data/[param].json.js
@@ -0,0 +1,24 @@
+
+export function getStaticPaths() {
+ return [
+ {
+ params: {
+ param: 'one'
+ }
+ },
+ {
+ params: {
+ param: 'two'
+ }
+ },
+ ]
+}
+
+export function get({ params, request }) {
+ return {
+ body: JSON.stringify({
+ param: params.param,
+ pathname: new URL(request.url).pathname
+ })
+ };
+}
diff --git a/packages/astro/test/fixtures/api-routes/src/pages/old-api/onearg/[param].json.js b/packages/astro/test/fixtures/api-routes/src/pages/old-api/onearg/[param].json.js
new file mode 100644
index 000000000..63771f8e0
--- /dev/null
+++ b/packages/astro/test/fixtures/api-routes/src/pages/old-api/onearg/[param].json.js
@@ -0,0 +1,23 @@
+
+export function getStaticPaths() {
+ return [
+ {
+ params: {
+ param: 'one'
+ }
+ },
+ {
+ params: {
+ param: 'two'
+ }
+ },
+ ]
+}
+
+export function get(params) {
+ return {
+ body: JSON.stringify({
+ param: params.param
+ })
+ };
+}
diff --git a/packages/astro/test/fixtures/api-routes/src/pages/old-api/twoarg/[param].json.js b/packages/astro/test/fixtures/api-routes/src/pages/old-api/twoarg/[param].json.js
new file mode 100644
index 000000000..ab71d6896
--- /dev/null
+++ b/packages/astro/test/fixtures/api-routes/src/pages/old-api/twoarg/[param].json.js
@@ -0,0 +1,24 @@
+
+export function getStaticPaths() {
+ return [
+ {
+ params: {
+ param: 'one'
+ }
+ },
+ {
+ params: {
+ param: 'two'
+ }
+ },
+ ]
+}
+
+export function get(params, request) {
+ return {
+ body: JSON.stringify({
+ param: params.param,
+ pathname: new URL(request.url).pathname
+ })
+ };
+}
diff --git a/packages/astro/test/fixtures/ssr-dynamic/src/pages/api/products/[id].js b/packages/astro/test/fixtures/ssr-dynamic/src/pages/api/products/[id].js
index 2d619ee74..4d96b62a5 100644
--- a/packages/astro/test/fixtures/ssr-dynamic/src/pages/api/products/[id].js
+++ b/packages/astro/test/fixtures/ssr-dynamic/src/pages/api/products/[id].js
@@ -1,5 +1,5 @@
-export function get(params) {
+export function get({ params }) {
return {
body: JSON.stringify(params)
};