Skip to content

finom/vovk

Repository files navigation

vovk
RESTful RPC for Next.js

Transforms Next.js into a powerful REST API platform with RPC capabilities.

🎉 Vovk 2.0 is released. Read more →

Documentation     Discord     Code Examples     vovk-zod     vovk-hello-world     vovk-react-native-example

npm version  TypeScript  Build status


Example back-end Controller Class:

// /src/modules/post/PostController.ts
import { get, prefix, type VovkRequest } from 'vovk';
import PostService from './PostService';
 
@prefix('posts')
export default class PostController {
  /**
   * Create a comment on a post
   * POST /api/posts/:postId/comments
   */
  @post(':postId/comments')
  static async createComment(
    // decorate NextRequest type with body and query types
    req: VovkRequest<
      { content: string; userId: string }, 
      { notificationType: 'push' | 'email' }
    >,
    { postId }: { postId: string } // params
  ) {
    // use standard Next.js API to get body and query
    const { content, userId } = await req.json();
    const notificationType = req.nextUrl.searchParams.get('notificationType');
 
    // perform the request to the database in a custom service
    return PostService.createComment({ 
      postId, content, userId, notificationType,
    });
  }
}

Example component that uses the auto-generated client library:

'use client';
import { useState } from 'react';
import { PostController } from 'vovk-client';
import type { VovkReturnType } from 'vovk';
 
export default function Example() {
  const [response, setResponse] = useState<VovkReturnType<typeof PostController.createComment>>();
 
  return (
    <>
      <button
        onClick={async () => setResponse(
          await PostController.createComment({
            body: { 
              content: 'Hello, World!', 
              userId: '1', 
            },
            params: { postId: '69' },
            query: { notificationType: 'push' }
          })
        )}
      >
        Post a comment
      </button>
      <div>{JSON.stringify(response)}</div>
    </>
  );
}

Alternatively, the resource can be fetched wit the regular fetch function:

fetch('/api/posts/69?notificationType=push', {
  method: 'POST',
  body: JSON.stringify({ 
    content: 'Hello, World!', 
    userId: '1', 
  }),
})