You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
`server$()` allows you to define functions that execute exclusively on the server, making it ideal for server-only operations and database access. It functions as an RPC (Remote Procedure Call) mechanism between the client and server, similar to a traditional HTTP endpoint, but strongly typed with TypeScript and easier to maintain.
24
24
25
-
Your new function will have the following signature:
26
-
`([AbortSignal, ] ...): Promise<T>`
25
+
> `server$` can accept any number of arguments and return any value that can be serialized by Qwik, that includes primitives, objects, arrays, bigint, JSX nodes and even Promises, just to name a few.
26
+
27
27
28
-
`AbortSignal` is optional, and allows you to cancel a long running request by terminating the connection.
29
-
Please note that depending on your server runtime, the function on the server may not terminate immediately. It depends on how client disconnections are handled by the runtime.
28
+
`AbortSignal` is optional, and allows you to cancel a long running request by terminating the connection.
29
+
Your new function will have the following signature:
30
+
`([AbortSignal, ...yourOtherArgs]): Promise<T>`
31
+
> Please note that depending on your server runtime, the function on the server may not terminate immediately. It depends on how client disconnections are handled by the runtime.
`server$` can also read the HTTP cookies, headers, or environment variables, using `this`. In this case you will need to use a function instead of an arrow function.
71
+
## Accessing Request Information with `RequestEvent`
72
+
73
+
When using `server$`, you have access to the `RequestEvent` object through `this`. This object provides useful information about the HTTP request, including environment variables, cookies, URL, and headers. Here's how you can use it:
74
+
75
+
### Environment Variables
76
+
77
+
You can access environment variables using `this.env.get()`.
66
78
67
79
```tsx
68
-
// Notice that the wrapped function is declared as an `async function`
// The `this` is the `RequestEvent` object, which contains
71
-
// the HTTP headers, cookies, and environment variables.
72
-
const db =createClient(this.env.get('DB_KEY'));
73
-
if (this.cookie.get('user-session')) {
74
-
awaitdb.from('users').insert({
75
-
id,
76
-
fullName,
77
-
address
78
-
});
79
-
return {
80
-
success: true,
80
+
exportconst getEnvVariable =server$(
81
+
function () {
82
+
const dbKey =this.env.get('DB_KEY');
83
+
console.log('Database Key:', dbKey);
84
+
returndbKey;
85
+
}
86
+
);
87
+
```
88
+
89
+
### Cookies
90
+
91
+
You can read cookies using `this.cookie.get()` and `this.cookie.set()`.
92
+
93
+
> When using `handleCookies` (in our example below) if it's used within a `useTask$` function that runs during the initial request, setting cookies won’t work as expected. This is because, during server-side rendering (SSR), the response is streamed, and HTTP requires all headers to be set before sending the first response. However, if handleCookies is used in useVisibleTask$, this issue doesn’t occur. If you need to set cookies for the initial document request you can use `plugin@<name>.ts` or Middleware.
You can access the request URL and its components using `this.url`.
110
+
111
+
```tsx
112
+
exportconst getRequestUrl =server$(
113
+
function () {
114
+
const requestUrl =this.url;
115
+
console.log('Request URL:', requestUrl);
116
+
returnrequestUrl;
85
117
}
86
-
})
118
+
);
87
119
```
88
120
89
-
> Server$ can accept any number of arguments and return any value that can be serialized by Qwik, that includes primitives, objects, arrays, bigint, JSX nodes and even Promises, just to name a few.
121
+
### Headers
90
122
123
+
You can read headers using `this.headers.get()`.
124
+
125
+
```tsx
126
+
exportconst getHeaders =server$(
127
+
function () {
128
+
const userAgent =this.headers.get('User-Agent');
129
+
console.log('User-Agent:', userAgent);
130
+
returnuserAgent;
131
+
}
132
+
);
133
+
```
134
+
135
+
### Using Multiple RequestEvent Information
136
+
137
+
Here's an example that combines environment variables, cookies, URL, and headers in a single function.
`server$` can return a stream of data by using an async generator. This is useful for streaming data from the server to the client.
174
+
`server$` can return a stream of data by using an async generator function, which is useful for streaming data from the server to the client.
95
175
96
-
Terminating the generator on the client side (e.g. by calling `return()` on the generator, or by breaking out from your async for-loop) will terminate the connection. As with `AbortSignal` -
97
-
how the generator will terminate on the server side depends on the server runtime and how client disconnects are handled.
176
+
Terminating the generator on the client side (e.g., by calling `.return()` on the generator or by breaking out from your async for-of loop) will terminate the connection. Similar to `AbortSignal`, how the generator terminates on the server side depends on the server runtime and how client disconnects are handled.
// call the async stream function and wait for the response
125
-
const response =awaitstream();
126
-
// use a for-await-of loop to asynchronously iterate over the response
127
-
forawait (const index ofresponse) {
128
-
// add each index from the response to the message value
129
-
message.value+=` ${index}`;
205
+
onClick$={
206
+
async () => {
207
+
// call the async stream function and wait for the response
208
+
const response =awaitstreamFromServer();
209
+
// use a for-await-of loop to asynchronously iterate over the response
210
+
forawait (const value ofresponse) {
211
+
// add each value from the response to the message value
212
+
message.value+=` ${value}`;
213
+
}
214
+
// do anything else
130
215
}
131
-
}}
216
+
}
132
217
>
133
218
start
134
219
</button>
@@ -163,3 +248,6 @@ When using `server$`, it's important to understand how [middleware functions](/d
163
248
To ensure that a middleware function runs for both types of requests, it should be defined in the `plugin.ts` file. This ensures that the middleware is executed consistently for all incoming requests, regardless of whether they are normal page requests or `server$` requests.
164
249
165
250
By [defining middleware in the `plugin.ts`](/docs/advanced/plugints) file, developers can maintain a centralized location for shared middleware logic, ensuring consistency and reducing potential errors or oversights.
0 commit comments