Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

proz

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

proz

TypeScript-powered HTTP RPC library for your own server and client

  • 0.0.0
  • unpublished
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
0
Maintainers
1
Weekly downloads
 
Created
Source

proz

proz is a functional RPC-based API Layer for your Client-Server-Apps, which allows you to call your fully typed API methods directly inside your client.

tl;dr: just scroll down for a complete example.

This Library is currently a work in progress and not ready for production.

Summary

proz empowers you to move parts of your business logic from your client to your server, so your client can take care of the UI, and your server can do the data crunching.

  • proz makes heavy use of TypeScript's type inference, reducing the amount of types you need to manually define and maintain. It's fully typed – even if you don't define any types at all.
  • proz does not specify nor recommend how your API should be structured. Because it's just a (maybe huge) collection of functions, which you created for your own needs. You don't need to build a REST- or GraphQL-API for your own Backend-for-Frontend, just a convenient and simple RPC-like interface.
  • Supports async middleware.
  • Supports schema validation of your request params and body.
  • Includes an autogenerated API client, without any compilation or babel-plugins. It's fully powered by TypeScript.
  • proz' API client is a tiny 250 Bytes (150 Bytes gzipped).

Info: This package is native ESM.

Details

proz consists of a Resolver and Client.

The Resolver is the server part, where you define your API methods as Queries and Mutations. The Resolver takes a request, resolves which API method should be executed, executes it (with its middleware), and returns the result.

The Client is an easy-to-use fully typed and tiny Client, which calls the Resolver. The Client doesn't need any autogeneration or babel plugin. It's a JavaScript Proxy , which knows about all the type definitions of your Resolver. So it knows which methods are defined, what parameters they expect, and what data they return. Because it's only powered by types, it's a measly 250 Bytes (150 Bytes gzipped).

Example

import { proz } from 'proz'

// Define Queries

// Use pipe() to create middlewares for your API methods.
const todosCtx = proz.pipe(
  // use your own authentication middlewares
  async (ctx) => {
    const user = await db.user.findById(ctx.req.cookies['user_id'])
    return { ...ctx, user }
  },
  // Validate and sanitize the request's query params.
  // Supports zod, yup out of the box. Or use your own validator.
  proz.params(yup.object({
    status: yup.string().oneOf(['todo', 'done']),
    limit: yup.number().max(20)
  }))
)

// proz.query() creates a query handlers (GET request) for your API.
const todos = proz.query(todosCtx, async (ctx) => {
  const todos = await db.todo.findMany({
    where: { status: ctx.params.status }
    limit: ctx.params.limit || 10
  })
  return todos
})

// You can define as many queries as you like. This is just an example and not
// a guideline. Nothing prohibits you from defining separate queries for
// `allTodos()`, `openTodos()`, `doneTodos()`.

const openTodos = proz.query(async () => {
  const todos = await db.todo.findMany({
    where: { status: 'open' }
  })
  return todos
})

const doneTodos = proz.query(async () => {
  const todos = await db.todo.findMany({
    where: { status: 'done' }
  })
  return todos
})

// Define Mutations

const addTodoCtx = proz.pipe(
  authentication,
  // Validate and sanitize the request's body with yup, zod, ...
  proz.body(yup.object({ id: yup.string().required() })) 
)

// proz.mutation() creates a mutation resolver (POST request) for your API.
const addTodo = proz.mutation(addTodoCtx, async (ctx) => {
  // ctx.body is validated!
  const todo = await db.todo.create({
    ...ctx.body,
    userId: ctx.user.id // ctx is typesafe from your middlewares
  })
  return todo
)

// Create your proz instance and use your queries and mutations.
// Use this for example in Next.js inside a file: api/rpc/[...proz].ts

import { createProzResolver } from 'proz'

const prozResolver = createProzResolver({
  todos,
  openTodos,
  doneTodos,
  addTodo
})

// We need this later for our client.
export type ApiResolver = typeof prozResolver

export default async (req, res) => {
  const data = prozServer.handle(req, res)
  res.json(data)
}

// lib/api-client.ts

import { createProzClient } from 'proz'
import type { ApiResolver } from './whatever'

// Create your api client and feed it with the type of the prozServer.
const api = createProzClient<ApiResolver>({
  fetch: ({ proc, method, body, params }) => {
    // Use your favorite HTTP library.
    return ky(`/api/${proc}`, {
      method,
      json: body,
      searchParams: params
    }).json()
  }
})

// client/ui-component.ts

// Simply use your API client inside your UI.
// The responses and query params are automatically fully typed,
// using the schemas and return type from your API handlers.

// Queries are GET-Requests and use the Request query (URL Params) as input.
const todos = await api.query.todos({ status: 'todo' })
const openTodos = await api.query.openTodos()
const doneTodos = await api.query.doneTodos()

async function handleAddClick() {
  // Mutations are POST-Requests and use the Request body as input.
  const newTodo = await api.mutate.addTodo({
    name: 'Buy Milk' // body is fully typed using your TodoSchema
  })

  console.log(newTodo) // Of course, newTodo is fully typed!
}

<button onClick={handleAddClick}>
  Add Todo
</button>

Wishlist

What I'm thinking about adding...

Keywords

FAQs

Package last updated on 29 May 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc