Git Product home page Git Product logo

httpc's Introduction

httpc

httpc is a javascript/typescript framework for building function-based API with minimal code and end-to-end type safety.

Quick glance

You just write functions and export them. No need to worry how the server will execute them.

function add(a: number, b: number) {
    return a + b;
}

function greet(name: string) {
    return `Hello ${name}`;
}

export default {
    add,
    greet,
}

From the client you can call server functions like normal javascript functions with a natural syntax.

import createClient from "@your-package/api-client";

const client = createClient({
    endpoint: "http://api.domain.com"
});

let result = await client.add(1, 2);
// result: 3

let message = await client.greet("Edith");
// message: "Hello Edith"

Key principle

httpc is an abstraction over the standard HTTP protocol. With httpc you can build an API that speaks functions, arguments and return values, not http verbs, headers, resource paths, data serialization…

The httpc framework hides all the complexity of the underling HTTP while keeping you focused on what matters: the function logic.

Main features

Middlewares

Run common logic via middlewares.

import { httpCall } from "@httpc/server";

const getPostById = httpCall(
    Authenticated(),    // <-- authentication check
    Validate(String),   // <-- parameters validation
    Cache("5m"),        // <-- result caching
    async (postId: string) => {
        const post = await db.select("posts").where("id", postId);
        if (!post) {
            throw new NotFoundError();
        }

        return post;
    }
);

Context ubiquity

Access the request context from everywhere in your application. Be in a handler, middleware o service logic, the context is always available with no need to pass parameters around.

async function getPosts() {
    const { user } = useContext();

    let category = "news";
    if (user) {
        category = user.preferredCategory;
        trace("Getting user preferred posts");
    }
    
    return await db.select("posts").where("category", category);
}

function trace(message: string) {
    const { requestId } = useContext();
    console.log(`[req:${requestId}] ${message}`);
}

Hooks

Hooks encapsulate common logic around the request context. By convention hooks adopt the use prefix.

async function addNewComment(postId: string, message: string) {
    const user = useUser();

    if (!useIsAuthorized("comment:create")) {
        throw new ForbiddenError("Cannot add comments");
    }

    return await db.createComment({
        userId: user.id,
        postId,
        message
    });
}

@httpc/kit offers several builtin hooks to cache data, to perform authorization checks, to make transactions…

Serverless

You can host a full httpc API inside a serverless environment like Vercel, AWS Lambda or Netlify functions. This gives the advantage to deploy a single serverless function handling the whole API.

For example with Vercel, you can expose all your API functions:

//file: api/index.ts

import { createHttpCVercelAdapter } from "@httpc/adapter-vercel";
import calls from "../calls";

export default createHttpCVercelAdapter({
    calls,
    log: "info"
});

Then, you can call API functions from pages with full type checking:

//file: pages/home.tsx

import { createClient, ClientDef } from "@httpc/client";
import { useQuery, useMutation } from "react-query";
import type calls from "../calls"; // <-- import calls definition

// create a typed client
const client = createClient<ClientDef<typeof calls>>();

export default function Home() {
  const posts = useQuery(["posts"], () => client.posts.getLatest());

  return (
    <div class="container">
      {posts.data.map(post =>
        <div class="post">
          <h2>{post.title}</h2>
          <p>{post.text}</p>
        </div>
      )}
    </div>
  );
}

Extensive type safety

Customize builtin objects to fit your needs, while keeping autocompletion and type checking working.

You can extend the request context:

/// <reference types="@httpc/kit/env" />

interface IHttpCContext {
    // example custom property
    environment: string

    // other custom properties here
    // ...
}

There're many entities available to extend. For example you can redefine the user object with custom properties:

interface IUser {
    firstName: string
    lastName: string
}

Builtin functions and hooks will get the custom definitions and let you use them with type checking.

const { firstName } = useUser();

Custom client generation

With @httpc/cli you can generate a specific client for your API. The generated client ensures type safety and a smooth experience with a natural syntax developers are familiar with.

const user = await client.users.search("[email protected]");
const posts = await client.posts.getByUser(user.id);
const newComment = await client.posts.addComment(posts[0].id, {
    text: "Hello",
    userId: user.id
});

Beyond httpc

The httpc server is not limited to function calls. It can handle browser form submissions, web hook callbacks, standard redirects… and, in general, any http request. By using Parsers (there're many builtin), you can customize how the server processes a request.

Handling standard http requests is essential in scenarios where you don't control the client. An httpc server allows you to responds to both functions and common http requests.

httpc family

@httpc/server: the httpc core component allowing function calls over the standard http protocol

@httpc/client: typed interface used by consumers to interact safely with functions exposed by an httpc server

@httpc/kit: rich toolbox of builtin components to manage common use cases and business concerns like authentication, validation, caching and logging

@httpc/cli: commands to setup a project, generate clients, manage versioning and help with common tasks

@httpc/adapter-*: various adapters to host an httpc API inside environment like vercel, netlify functions, aws lambda and similar

Project status

httpc is experimental. It's in its infancy stage. You can try it, adopt it in hobby projects. But it's not ready for production.
The API is not stable yet. Breaking changes will happen.
httpc is under heavy development. You can checkout the Changelog and the Roadmap for future features.

Involvement

Community

You can join on Discord and follow the development, discuss contributions, receive support or ask for help. Participation in Github discussion is fine too.

File an Issue

For any bugs, feature requests or proposals you can file an issue. All issues are available on Github.

Contributing

All contribution are welcome. Any PR, issue and feedback is appreciated. Checkout the contribution guide.

License

MIT © Giuseppe La Torre

httpc's People

Contributors

github-actions[bot] avatar giuseppelt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

michealroberts

httpc's Issues

outputDirectory path is not relative to current directory when create-httpc

I tried pnpm create httpc but there is no output file or folder.

According to this log, the outputDirectory is assumed as relative path from node_modules/create-httpc folder

pnpm

%% pnpm create httpc
.../share/pnpm/store/v3/tmp/dlx-53028    |  +33 +++
Packages are hard linked from the content-addressable store to the virtual store.
  Content-addressable store is at: /Users/miyamonz/.local/share/pnpm/store/v3
  Virtual store is at:             ../../../../.local/share/pnpm/store/v3/tmp/dlx-53028/node_modules/.pnpm
.../share/pnpm/store/v3/tmp/dlx-53028    | Progress: resolved 33, reused 33, downloaded 0, added 33, done
✔ Select a template you want to start with › Server blank
✔ Specify the output directory … ./
? Output directory(/Users/miyamonz/.local/share/pnpm/store/v3/tmp/dlx-53028/node_modules/.pnpm/[email protected]/node_modules/create-httpc) not empty, all content will be deleted. Confirm? › (Y/n)

npm

%% npm init httpc
Need to install the following packages:
  [email protected]
Ok to proceed? (y)
✔ Select a template you want to start with › Kit blank
✔ Specify the output directory …
✔ Output directory(/Users/miyamonz/.npm/_npx/fab980724a10a9dd/node_modules/create-httpc) not empty, all content will be deleted. Confirm? … yes

version: 0.1.0

maybe this line is related to this issue.

cwd: path.dirname(fileURLToPath(import.meta.url)) // path local to the package

Good one!

Just found this mentioned on some reddit post.
I've been doing some research for the past few months around functional, RPC like framework (correlated with tRPC, ts-rest, zodios, telefunc, blitz-rpc etc.) but haven found anything fulfilling my needs. But this seems like the one! I love the idea and simplicity. This is what I need.

What is current state of the project?

I would love to contribute to the project to help growth and fast v1 release <3 (currently busy at work so it can be hard atm).
For sure you have my star and follow. Looking forward to what this can emerge into.
Keep good work :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.