Конечные точки

Функция промежуточного ПО, которая возвращает ответ, называется конечной точкой. Конечные точки полезны для возврата данных, таких как RESTful API, GraphQL API, JSON, XML, обратный прокси или любые другие типы API, где вам необходимо контролировать все аспекты HTTP-ответа. Возврат ответа (например, с помощью json) остановит выполнение последующих функций промежуточного ПО после этой точки в цепочке промежуточного ПО.

Все конечные точки получают API RequestEvent для управления ответом конечной точки.

Например, при переходе по URL /greet/ эта конечная точка вернет {"hello": "world"}.

File: src/routes/greet/index.tsx

import { type RequestHandler } from '@builder.io/qwik-city';
 
export const onGet: RequestHandler = async ({ json }) => {
  json(200, { hello: 'world' });
};

Отправка ответа - это то, что отличает конечную точку от промежуточного ПО. Поэтому отправка ответа (например, с помощью json()) будет неявно останавливать цепочку промежуточного ПО.

Создание обратного прокси-сервера с использованием fetch

Обратный прокси может быть создан с помощью метода fetch() для выполнения запроса к другому серверу, а затем с помощью метода end() для отправки ответа обратно клиенту.

import type { RequestHandler } from '@builder.io/qwik-city';
 
export const onGet: RequestHandler = async ({ send, url }) => {
  const response = await fetch(
    new URL('/demo/qwikcity/middleware/json/', url)
  );
  send(response.status, await response.text());
};

Создание потока ответа вручную

Конечные точки могут вручную записывать в поток ответа HTTP, используя метод getWritableStream(). Это может быть полезно для создания потоковой конечной точки, например, конечной точки событий, отправляемых сервером.

import type { RequestHandler } from '@builder.io/qwik-city';
 
export const onGet: RequestHandler = async (requestEvent) => {
  const writableStream = requestEvent.getWritableStream();
  const writer = writableStream.getWriter();
  const encoder = new TextEncoder();
 
  writer.write(encoder.encode('Hello World\n'));
  await wait(100);
  writer.write(encoder.encode('After 100ms\n'));
  await wait(100);
  writer.write(encoder.encode('After 200ms\n'));
  await wait(100);
  writer.write(encoder.encode('END'));
  writer.close();
};
 
const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

Конечная точка vs server$

Конечные точки - это низкоуровневые API, которые дают разработчикам полный контроль над HTTP-ответом. Они рекомендуются только в том случае, если вам нужно создать API, который будет потребляться внешним объектом, например, мобильным приложением или сторонним сервисом.

Функции server$ обычно являются лучшим вариантом, когда вам нужно выполнить некоторый код на сервере и вернуть ответ обратно в приложение. server$ сильно типизирован и предоставляют более удобный API для возврата данных.

Участники

Спасибо всем участникам, которые помогли сделать эту документацию лучше!

  • adamdbradley
  • manucorporat
  • mhevery
  • CoralWombat
  • hamatoyogi
  • igorbabko
  • mrhoodz
  • EamonHeffernan
  • kumarasinghe
  • electather
  • wtlin1228
  • PatrickJS
  • the-r3aper7