Tech Sessions

07/06/2023

RPC is back baby!

Solid Start

import { createServerAction$, redirect } from "solid-start/server";
 
function EnrollmentPage() {
  const [enrolling, { Form }] = createServerAction$(async (form: FormData, { request }) => {
    const subject = form.get("subject") as string;
    const user = await getLoggedInUser(request);
    await prisma.enrollment.create({
      data: {
        userId: user.id,
        subject
      }
    });
    return redirect("/enrollment");
  });
  return (
    <Form>
      <input type="hidden" name="subject" value="Defense against the Dark Arts" />
      <button type="submit" disabled={enrolling.pending}>
        Enroll
      </button>
    </Form>
  );
}

Qwik City

import { component$ } from '@builder.io/qwik';
import { routeAction$, Form } from '@builder.io/qwik-city';
 
export const useAddUser = routeAction$(async (user) => {
  const userID = await db.users.add(user);
  return {
    success: true,
    userID,
  };
});
 
export default component$(() => {
  const action = useAddUser();
  return (
    <Form action={action}>
      <input name="name" />
      <button type="submit">Add user</button>
      {action.value?.success && <p>User added successfully</p>}
    </Form>
  );
});

Next

import { cookies } from 'next/headers';
 
// Server action defined inside a Server Component
export default function AddToCart({ productId }) {
  async function addItem(data) {
    'use server';
 
    const cartId = cookies().get('cartId')?.value;
    await saveToDb({ cartId, data });
  }
 
  return (
    <form action={addItem}>
      <button type="submit">Add to Cart</button>
    </form>
  );
}

Umm...

Looks familiar?

<?php  
$name=$_POST["name"];//receiving name field value in $name variable  
$password=$_POST["password"];//receiving password field value in $password variable  
  
echo "Welcome: $name, your password is: $password";  
?>  
<form action="login.php" method="post">   
<table>   
<tr><td>Name:</td><td> <input type="text" name="name"/></td></tr>  
<tr><td>Password:</td><td> <input type="password" name="password"/></td></tr>   
<tr><td colspan="2"><input type="submit" value="login"/>  </td></tr>  
</table>  
</form>   

Why are we doing this?

  • Eliminate the need to build an API
  • Allow for progressive enhancement
  • "Use the platform"
  • Server can handle navigation
  • What else?

What are the downsides?

  • "If nothing magically works, nothing magically breaks"
  • Requires a compiler to work
  • Augmenting Javascript/HTML semantics
  • Potential security vulnerabilities (variables from outer scope are injected)
  • What else?

VENN Tech Sessions

By Roman Sandler

VENN Tech Sessions

  • 341