Skip to content

Commit

Permalink
feat: upper case the name of the endpoints (#7783)
Browse files Browse the repository at this point in the history
Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com>
Co-authored-by: Yan Thomas <61414485+Yan-Thomas@users.noreply.github.com>
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
  • Loading branch information
4 people committed Aug 8, 2023
1 parent 42fc57e commit 0f06255
Show file tree
Hide file tree
Showing 45 changed files with 116 additions and 53 deletions.
35 changes: 35 additions & 0 deletions .changeset/twelve-coats-rush.md
@@ -0,0 +1,35 @@
---
'astro': major
---

Lowercase names for endpoint functions are now deprecated.

Rename functions to their uppercase equivalent:

```diff
- export function get() {
+ export function GET() {
return new Response(JSON.stringify({ "title": "Bob's blog" }));
}

- export function post() {
+ export function POST() {
return new Response(JSON.stringify({ "title": "Bob's blog" }));
}

- export function put() {
+ export function PUT() {
return new Response(JSON.stringify({ "title": "Bob's blog" }));
}

- export function all() {
+ export function ALL() {
return new Response(JSON.stringify({ "title": "Bob's blog" }));
}

// you can use the whole word "DELETE"
- export function del() {
+ export function DELETE() {
return new Response(JSON.stringify({ "title": "Bob's blog" }));
}
```
2 changes: 1 addition & 1 deletion packages/astro/src/assets/image-endpoint.ts
Expand Up @@ -24,7 +24,7 @@ async function loadRemoteImage(src: URL) {
/**
* Endpoint used in dev and SSR to serve optimized images by the base image services
*/
export const get: APIRoute = async ({ request }) => {
export const GET: APIRoute = async ({ request }) => {
try {
const imageService = await getConfiguredImageService();

Expand Down
6 changes: 3 additions & 3 deletions packages/astro/src/core/endpoint/index.ts
Expand Up @@ -7,13 +7,13 @@ import type {
Params,
} from '../../@types/astro';
import type { Environment, RenderContext } from '../render/index';

import { renderEndpoint } from '../../runtime/server/index.js';
import { ASTRO_VERSION } from '../constants.js';
import { AstroCookies, attachToResponse } from '../cookies/index.js';
import { AstroError, AstroErrorData } from '../errors/index.js';
import { warn } from '../logger/core.js';
import { callMiddleware } from '../middleware/callMiddleware.js';

const clientAddressSymbol = Symbol.for('astro.clientAddress');
const clientLocalsSymbol = Symbol.for('astro.locals');

Expand Down Expand Up @@ -119,11 +119,11 @@ export async function callEndpoint<MiddlewareResult = Response | EndpointOutput>
onRequest as MiddlewareEndpointHandler,
context,
async () => {
return await renderEndpoint(mod, context, env.ssr);
return await renderEndpoint(mod, context, env.ssr, env.logging);
}
);
} else {
response = await renderEndpoint(mod, context, env.ssr);
response = await renderEndpoint(mod, context, env.ssr, env.logging);
}

if (response instanceof Response) {
Expand Down
38 changes: 33 additions & 5 deletions packages/astro/src/runtime/server/endpoint.ts
@@ -1,28 +1,56 @@
import type { APIContext, EndpointHandler, Params } from '../../@types/astro';
import { type LogOptions, warn } from '../../core/logger/core.js';

function getHandlerFromModule(mod: EndpointHandler, method: string) {
function getHandlerFromModule(mod: EndpointHandler, method: string, logging: LogOptions) {
const lowerCaseMethod = method.toLowerCase();

// TODO: remove in Astro 4.0
if (mod[lowerCaseMethod]) {
warn(
logging,
'astro',
`Lower case endpoint names are deprecated and will not be supported in Astro 4.0. Rename the endpoint ${lowerCaseMethod} to ${method}.`
);
}
// If there was an exact match on `method`, return that function.
if (mod[method]) {
return mod[method];
}

// TODO: remove in Astro 4.0
if (mod[lowerCaseMethod]) {
return mod[lowerCaseMethod];
}
// TODO: remove in Astro 4.0
// Handle `del` instead of `delete`, since `delete` is a reserved word in JS.
if (method === 'delete' && mod['del']) {
return mod['del'];
}
// TODO: remove in Astro 4.0
// If a single `all` handler was used, return that function.
if (mod['all']) {
return mod['all'];
}
if (mod['ALL']) {
return mod['ALL'];
}
// Otherwise, no handler found.
return undefined;
}

/** Renders an endpoint request to completion, returning the body. */
export async function renderEndpoint(mod: EndpointHandler, context: APIContext, ssr: boolean) {
export async function renderEndpoint(
mod: EndpointHandler,
context: APIContext,
ssr: boolean,
logging: LogOptions
) {
const { request, params } = context;
const chosenMethod = request.method?.toLowerCase();
const handler = getHandlerFromModule(mod, chosenMethod);
if (!ssr && ssr === false && chosenMethod && chosenMethod !== 'get') {

const chosenMethod = request.method?.toUpperCase();
const handler = getHandlerFromModule(mod, chosenMethod, logging);
// TODO: remove the 'get' check in Astro 4.0
if (!ssr && ssr === false && chosenMethod && chosenMethod !== 'GET' && chosenMethod !== 'get') {
// eslint-disable-next-line no-console
console.warn(`
${chosenMethod} requests are not available when building a static site. Update your config to \`output: 'server'\` or \`output: 'hybrid'\` with an \`export const prerender = false\` to handle ${chosenMethod} requests.`);
Expand Down
@@ -1,5 +1,5 @@
import type { APIRoute } from 'astro';

export const get: APIRoute = async function () {
export const GET: APIRoute = async function () {
return new Response(new Uint8Array([0xff]));
};
Expand Up @@ -14,7 +14,7 @@ export function getStaticPaths() {
]
}

export function get({ params, request }) {
export function GET({ params, request }) {
return {
body: JSON.stringify({
param: params.param,
Expand Down
@@ -1,5 +1,5 @@

export function post({ cookies }) {
export function POST({ cookies }) {
const mode = cookies.get('prefs').json().mode;

cookies.set('prefs', {
Expand Down
Expand Up @@ -5,7 +5,7 @@ export async function getStaticPaths() {
];
}

export async function get() {
export async function GET() {
return {
body: JSON.stringify({
title: '[slug]'
Expand Down
@@ -1,4 +1,4 @@
export async function get() {
export async function GET() {
const docs = await import.meta.glob('./*.md', { eager: true });
return {
body: JSON.stringify(Object.values(docs).map(doc => doc.frontmatter)),
Expand Down
@@ -1,6 +1,6 @@
import { getHeadings } from './with-layout.md';

export async function get() {
export async function GET() {
return {
body: JSON.stringify({
headings: getHeadings(),
Expand Down
@@ -1,6 +1,6 @@
import { rawContent, compiledContent } from './basic.md';

export async function get() {
export async function GET() {
return {
body: JSON.stringify({
raw: rawContent(),
Expand Down
@@ -1,6 +1,6 @@
import { frontmatter } from './vite-env-vars.md';

export async function get() {
export async function GET() {
return {
body: JSON.stringify(frontmatter),
}
Expand Down
@@ -1,6 +1,6 @@
import { getEntry, getEntries } from 'astro:content';

export async function get() {
export async function GET() {
const welcomePost = await getEntry('blog', 'welcome');

if (!welcomePost?.data) {
Expand Down
Expand Up @@ -2,7 +2,7 @@ import { getCollection } from 'astro:content';
import * as devalue from 'devalue';
import { stripAllRenderFn } from '../utils.js';

export async function get() {
export async function GET() {
const withoutConfig = stripAllRenderFn(await getCollection('without-config'));
const withSchemaConfig = stripAllRenderFn(await getCollection('with-schema-config'));
const withSlugConfig = stripAllRenderFn(await getCollection('with-custom-slugs'));
Expand Down
Expand Up @@ -2,7 +2,7 @@ import { getEntryBySlug } from 'astro:content';
import * as devalue from 'devalue';
import { stripRenderFn } from '../utils.js';

export async function get() {
export async function GET() {
const columbiaWithoutConfig = stripRenderFn(await getEntryBySlug('without-config', 'columbia'));
const oneWithSchemaConfig = stripRenderFn(await getEntryBySlug('with-schema-config', 'one'));
const twoWithSlugConfig = stripRenderFn(await getEntryBySlug('with-custom-slugs', 'interesting-two'));
Expand Down
@@ -1,6 +1,6 @@
import type { APIRoute } from "../../../../../src/@types/astro";

export const get = (async ({ params, request }) => {
export const GET = (async ({ params, request }) => {
const url = new URL(request.url);
const src = url.searchParams.get("src");

Expand Down
Expand Up @@ -7,7 +7,7 @@ export function getStaticPaths() {
}

/** @param {import('astro').APIContext} params */
export async function get({ params }) {
export async function GET({ params }) {
const { id } = params;
const author = await getEntry('authors-without-config', id);
if (!author) {
Expand Down
@@ -1,6 +1,6 @@
import { getCollection } from 'astro:content';

export async function get() {
export async function GET() {
const authors = await getCollection('authors-without-config');

return {
Expand Down
Expand Up @@ -7,7 +7,7 @@ export function getStaticPaths() {
}

/** @param {import('astro').APIContext} params */
export async function get({ params }) {
export async function GET({ params }) {
const { lang } = params;
const translations = await getEntry('i18n', lang);
if (!translations) {
Expand Down
@@ -1,6 +1,6 @@
import { getCollection } from 'astro:content';

export async function get() {
export async function GET() {
const translations = await getCollection('i18n');

return {
Expand Down
Expand Up @@ -2,7 +2,7 @@ import type { APIRoute } from "astro";

const slugs = ["one", undefined];

export const get: APIRoute = ({ params }) => {
export const GET: APIRoute = ({ params }) => {
return {
body: JSON.stringify({
slug: params.slug || "index",
Expand Down
@@ -1,4 +1,4 @@
export function get() {
export function GET() {
const object = {
name: 'Endpoint!!',
};
Expand Down
@@ -1,7 +1,7 @@
// Returns the file body for this non-HTML file.
// The content type is based off of the extension in the filename,
// in this case: about.json.
export async function get() {
export async function GET() {
return {
body: JSON.stringify({
name: 'Astro',
Expand Down
Expand Up @@ -2,7 +2,7 @@ import { promises as fs } from 'node:fs';

import type { APIRoute } from 'astro';

export const get: APIRoute = async function get() {
export const GET: APIRoute = async function get() {
try {
// Image is in the public domain. Sourced from
// https://en.wikipedia.org/wiki/File:Portrait_placeholder.png
Expand Down
@@ -1,6 +1,6 @@
import type { APIRoute } from 'astro';

export const get: APIRoute = async ({ params }) => {
export const GET: APIRoute = async ({ params }) => {
return {
body: JSON.stringify({
path: params.slug,
Expand Down
@@ -1,6 +1,6 @@
import type { APIRoute } from 'astro';

export const get: APIRoute = async ({ params }) => {
export const GET: APIRoute = async ({ params }) => {
return {
body: JSON.stringify({
foo: params.foo,
Expand Down
@@ -1,5 +1,5 @@

export function post() {
export function POST() {
return {
body: JSON.stringify({ ok: true })
};
Expand Down
@@ -1,6 +1,6 @@
import fs from 'node:fs';

export function get() {
export function GET() {
return {
body: 'ok'
};
Expand Down
@@ -1,7 +1,7 @@
/**
* @param {import('astro').APIContext} api
*/
export function get(ctx) {
export function GET(ctx) {
return {
body: JSON.stringify({
cookiesExist: !!ctx.cookies,
Expand Down
@@ -1,5 +1,5 @@

export function get() {
export function GET() {
return {
body: JSON.stringify([
{ name: 'lettuce' },
Expand All @@ -9,7 +9,7 @@ export function get() {
};
}

export async function post({ params, request }) {
export async function POST({ params, request }) {
const body = await request.text();
return new Response(body === `some data` ? `ok` : `not ok`, {
status: 200,
Expand Down
@@ -1,5 +1,5 @@
/** @type {import('astro').APIRoute} */
export function post({ cookies }) {
export function POST({ cookies }) {
cookies.set('foo', 'foo', {
httpOnly: true
});
Expand Down
@@ -1,5 +1,5 @@

export function get({ params }) {
export function GET({ params }) {
return {
body: JSON.stringify(params)
};
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/test/fixtures/ssr-locals/src/pages/api.js
@@ -1,5 +1,5 @@

export async function get({ locals }) {
export async function GET({ locals }) {
let out = { ...locals };

return new Response(JSON.stringify(out), {
Expand Down
Expand Up @@ -7,7 +7,7 @@ export async function getStaticPaths() {
];
}

export async function get() {
export async function GET() {
return {
body: JSON.stringify({
title: '[slug]'
Expand Down
@@ -1,8 +1,8 @@
export async function get() {
export async function GET() {
return {
body: JSON.stringify({
name: 'Astro Technology Company',
url: 'https://astro.build/'
})
}
}
}

0 comments on commit 0f06255

Please sign in to comment.