{"id":13454682,"url":"https://github.com/giuseppelt/httpc","last_synced_at":"2025-04-06T18:13:51.941Z","repository":{"id":65207491,"uuid":"496578366","full_name":"giuseppelt/httpc","owner":"giuseppelt","description":"Build function-based API with minimal code and end-to-end type safety","archived":false,"fork":false,"pushed_at":"2024-05-13T06:06:55.000Z","size":1940,"stargazers_count":192,"open_issues_count":2,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-30T17:11:26.324Z","etag":null,"topics":["api","client-generator","edge","javascript","json-api","rpc","rpc-api","serverless","typescript","workers"],"latest_commit_sha":null,"homepage":"https://httpc.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/giuseppelt.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-26T10:36:43.000Z","updated_at":"2025-03-11T08:10:07.000Z","dependencies_parsed_at":"2024-05-13T06:30:54.510Z","dependency_job_id":"84ab46ee-09d6-4fe0-8ae9-5bc4fbf43aaa","html_url":"https://github.com/giuseppelt/httpc","commit_stats":{"total_commits":71,"total_committers":2,"mean_commits":35.5,"dds":"0.014084507042253502","last_synced_commit":"5cf98a1a06a16e0a3eb6aa1d8ff4debc1ab0baa6"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giuseppelt%2Fhttpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giuseppelt%2Fhttpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giuseppelt%2Fhttpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giuseppelt%2Fhttpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/giuseppelt","download_url":"https://codeload.github.com/giuseppelt/httpc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247526761,"owners_count":20953143,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","client-generator","edge","javascript","json-api","rpc","rpc-api","serverless","typescript","workers"],"created_at":"2024-07-31T08:00:56.792Z","updated_at":"2025-04-06T18:13:51.920Z","avatar_url":"https://github.com/giuseppelt.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# httpc\nhttpc is a javascript/typescript framework for building function-based API with minimal code and end-to-end type safety.\n- [Documentation and tutorials](https://httpc.dev/docs)\n- [Community](https://httpc.dev/discord)\n- [Issues and feature requests](https://httpc.dev/issues)\n\n## Quick glance\nYou just write functions and export them. No need to worry how the server will execute them.\n```ts\nfunction add(a: number, b: number) {\n    return a + b;\n}\n\nfunction greet(name: string) {\n    return `Hello ${name}`;\n}\n\nexport default {\n    add,\n    greet,\n}\n```\n\nFrom the client you can call server functions like normal javascript functions with a natural syntax.\n```ts\nimport createClient from \"@your-package/api-client\";\n\nconst client = createClient({\n    endpoint: \"http://api.domain.com\"\n});\n\nlet result = await client.add(1, 2);\n// result: 3\n\nlet message = await client.greet(\"Edith\");\n// message: \"Hello Edith\"\n```\n\n## Key principle\n**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…\n\nThe **httpc** framework hides all the complexity of the underling HTTP while keeping you focused on what matters: the function logic.\n\n\n## Main features\n### Middlewares\nRun common logic via middlewares.\n```ts\nimport { httpCall } from \"@httpc/server\";\n\nconst getPostById = httpCall(\n    Authenticated(),    // \u003c-- authentication check\n    Validate(String),   // \u003c-- parameters validation\n    Cache(\"5m\"),        // \u003c-- result caching\n    async (postId: string) =\u003e {\n        const post = await db.select(\"posts\").where(\"id\", postId);\n        if (!post) {\n            throw new NotFoundError();\n        }\n\n        return post;\n    }\n);\n```\n\n### Context ubiquity\nAccess 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.\n```ts\nasync function getPosts() {\n    const { user } = useContext();\n\n    let category = \"news\";\n    if (user) {\n        category = user.preferredCategory;\n        trace(\"Getting user preferred posts\");\n    }\n    \n    return await db.select(\"posts\").where(\"category\", category);\n}\n\nfunction trace(message: string) {\n    const { requestId } = useContext();\n    console.log(`[req:${requestId}] ${message}`);\n}\n```\n\n### Hooks\nHooks encapsulate common logic around the request context. By convention hooks adopt the `use` prefix.\n```ts\nasync function addNewComment(postId: string, message: string) {\n    const user = useUser();\n\n    if (!useIsAuthorized(\"comment:create\")) {\n        throw new ForbiddenError(\"Cannot add comments\");\n    }\n\n    return await db.createComment({\n        userId: user.id,\n        postId,\n        message\n    });\n}\n```\n**@httpc/kit** offers several builtin hooks to cache data, to perform authorization checks, to make transactions…\n\n### Serverless\nYou can host a full **httpc** API inside a serverless environment like Vercel, AWS Lambda or Netlify functions.\nThis gives the advantage to deploy a single serverless function handling the whole API.\n\nFor example with Vercel, you can expose all your API functions:\n```ts\n//file: api/index.ts\n\nimport { createHttpCVercelAdapter } from \"@httpc/adapter-vercel\";\nimport calls from \"../calls\";\n\nexport default createHttpCVercelAdapter({\n    calls,\n    log: \"info\"\n});\n```\n\nThen, you can call API functions from pages with full type checking:\n```ts\n//file: pages/home.tsx\n\nimport { createClient, ClientDef } from \"@httpc/client\";\nimport { useQuery, useMutation } from \"react-query\";\nimport type calls from \"../calls\"; // \u003c-- import calls definition\n\n// create a typed client\nconst client = createClient\u003cClientDef\u003ctypeof calls\u003e\u003e();\n\nexport default function Home() {\n  const posts = useQuery([\"posts\"], () =\u003e client.posts.getLatest());\n\n  return (\n    \u003cdiv class=\"container\"\u003e\n      {posts.data.map(post =\u003e\n        \u003cdiv class=\"post\"\u003e\n          \u003ch2\u003e{post.title}\u003c/h2\u003e\n          \u003cp\u003e{post.text}\u003c/p\u003e\n        \u003c/div\u003e\n      )}\n    \u003c/div\u003e\n  );\n}\n```    \n\n### Extensive type safety\nCustomize builtin objects to fit your needs, while keeping autocompletion and type checking working.\n\nYou can extend the request context:\n```ts\n/// \u003creference types=\"@httpc/kit/env\" /\u003e\n\ninterface IHttpCContext {\n    // example custom property\n    environment: string\n\n    // other custom properties here\n    // ...\n}\n```\nThere're many entities available to extend. For example you can redefine the user object with custom properties:\n```ts\ninterface IUser {\n    firstName: string\n    lastName: string\n}\n```\nBuiltin functions and hooks will get the custom definitions and let you use them with type checking.\n```ts\nconst { firstName } = useUser();\n```\n\n### Custom client generation\nWith **@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.\n```ts\nconst user = await client.users.search(\"some@email.com\");\nconst posts = await client.posts.getByUser(user.id);\nconst newComment = await client.posts.addComment(posts[0].id, {\n    text: \"Hello\",\n    userId: user.id\n});\n```\n\n### Beyond httpc\nThe 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.\n\nHandling 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.\n\n\n## httpc family\n**@httpc/server**: the httpc core component allowing function calls over the standard http protocol\n\n**@httpc/client**: typed interface used by consumers to interact safely with functions exposed by an httpc server\n\n**@httpc/kit**: rich toolbox of builtin components to manage common use cases and business concerns like authentication, validation, caching and logging\n\n**@httpc/cli**: commands to setup a project, generate clients, manage versioning and help with common tasks\n\n**@httpc/adapter-\\***: various [adapters](https://httpc.dev/docs/adapters) to host an httpc API inside environment like vercel, netlify functions, aws lambda and similar\n\n\n\n## Project status\n**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.\n\u003cbr /\u003e\nThe API is not stable yet. Breaking changes will happen.\n\u003cbr /\u003e\n**httpc** is under heavy development. You can checkout the [Changelog](https://httpc.dev/changelog) and the [Roadmap](https://httpc.dev/roadmap) for future features.\n\n\n## Involvement\n### Community\nYou can join on [Discord](https://httpc.dev/discord) and follow the development, discuss contributions, receive support or ask for help. Participation in [Github discussion](https://httpc.dev/discuss) is fine too.\n\n### File an Issue\nFor any bugs, feature requests or proposals you can [file an issue](https://httpc.dev/issues/new). All issues are available on [Github](https://httpc.dev/issues).\n\n### Contributing\nAll contribution are welcome. Any PR, issue and feedback is appreciated. Checkout the [contribution guide](https://httpc.dev/contribute).\n\n\n## License\nMIT © [Giuseppe La Torre](https://github.com/giuseppelt)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiuseppelt%2Fhttpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgiuseppelt%2Fhttpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiuseppelt%2Fhttpc/lists"}