{"id":13767251,"url":"https://github.com/flock-community/zod-endpoints","last_synced_at":"2025-04-09T15:04:06.821Z","repository":{"id":46186775,"uuid":"284531584","full_name":"flock-community/zod-endpoints","owner":"flock-community","description":"Zod Router","archived":false,"fork":false,"pushed_at":"2021-11-08T18:39:28.000Z","size":750,"stargazers_count":182,"open_issues_count":5,"forks_count":7,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-04-09T15:01:17.349Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/flock-community.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-08-02T19:56:59.000Z","updated_at":"2025-03-27T16:25:38.000Z","dependencies_parsed_at":"2022-09-26T17:01:52.178Z","dependency_job_id":null,"html_url":"https://github.com/flock-community/zod-endpoints","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flock-community%2Fzod-endpoints","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flock-community%2Fzod-endpoints/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flock-community%2Fzod-endpoints/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flock-community%2Fzod-endpoints/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flock-community","download_url":"https://codeload.github.com/flock-community/zod-endpoints/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248055278,"owners_count":21040156,"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":[],"created_at":"2024-08-03T16:01:06.663Z","updated_at":"2025-04-09T15:04:06.781Z","avatar_url":"https://github.com/flock-community.png","language":"TypeScript","funding_links":[],"categories":["APIs and Servers"],"sub_categories":[],"readme":"\u003ca href=\"https://npmjs.org/package/zod-endpoints\" title=\"View this project on NPM\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/zod-endpoints.svg\" alt=\"NPM version\" /\u003e\u003c/a\u003e\n\u003ca href=\"./src/__tests__\" rel=\"nofollow\"\u003e\u003cimg src=\"./coverage.svg\" alt=\"coverage\"\u003e\u003c/a\u003e\n\n\n# Zod-endpoints\nContract first strictly typed endpoints. By defining endpoints as a zod schema, all the requests and responses can be checked and parsed at runtime. Moreover, the TypeScript compiler can check the in- and output types of the endpoints.\n\nIn this way the problem space of your application will become much smaller to begin with. By using zod-endpoints you can rely on the types during development and on validation at runtime. This yields requests and responses you can trust. The focus can shift more to defining business logic instead of input validation and error handling. \n\nThe schema can be used as a contract between consumer and producer. Drivers can be generated from the contract which ensures proper communication between a client and server. \n\n## Example project\n\n[Example](https://github.com/flock-community/zod-endpoints-example)\n\n## Simplified model\n\nZod-endpoints is based on a type representation of a http schema.  Below a simplyfied version of the model. The full model can be found [here](src/model.ts). The model is a union of requests which contains a union of response objects. Both request and response contain a union of body types.\n\n````ts\ntype Body = {\n    type: \"applictions/json\" | \"plain/html\"\n    content: any\n}\n\ntype Request = {\n    method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\"\n    path: [...string[]]\n    body: Body | ...Body\n}\n\ntype Response = {\n    status: number\n    body: Body | ...Body\n}\n\ntype Http = Request \u0026 {\n    responses: Response | ...Response\n}\n\ntype Schema = Http | ...Http\n````\n\n## Getting started\nFirst step is to define an endpoint by making use of the [zod-endpoints dsl](src/dsl.ts). Below you can find an example of a simple example. This example contains two endpoints to get and create a project.\n\n### Define endpoints\n````ts\nimport * as z from \"zod-endpoints\";\n\nconst project = z.object({\n  id: z.string().uuid(),\n  name: z.string(),\n})\n\nconst schema = z.endpoints([\n  z.endpoint({\n    name: \"GET_PROJECT\",\n    method: \"GET\",\n    path: [z.literal(\"projects\"), z.string().uuid()],\n    responses: [\n      z.response({\n        status: 200,\n        body:{\n          type: \"application/json\",\n          content: project\n        }       \n      }),\n    ],\n  }),\n  z.endpoint({\n    name: \"CREATE_PROJECT\",\n    method: \"POST\",\n    path: [z.literal(\"projects\")],\n    body:{\n      type: \"application/json\",\n      content: project\n    },\n    responses: [\n      z.response({\n        status: 201,  \n      }),\n    ],\n  }),\n]);\n````\n\n## Api\nThe endpoints can be convert into a service or a client with the [Api](src/api.ts) type. \n\n### Server\nFor the  type transforms the schema into an object of the requests. The key of the object is the name of the route the value is a function from the request to a union of the responses. This object is strict typed and exhaustive.\n\n```ts\nconst service = {\n  findProjectById: (id:string):Project =\u003e {},\n  createProject: (project:Project) =\u003e {},\n}\n````\n\n```ts\nimport * as z from \"zod-endpoints\";\n\nconst server: z.Api\u003ctypeof schema\u003e = {\n  \"GET_PROJECT\": ({path}) =\u003e findProjectById(path[1]).then(project =\u003e ({ \n    status: 200, \n    body:{\n      type: \"application/json\", \n      content:project\n    }\n  })),\n  \"CREATE_PROJECT\": ({body}) =\u003e createProject(body).Promise.resolve({ \n    status: 201 \n  }),\n};\n```\n\n### Client\nThe client implementation\n\n```ts\nconst http = (req: z.ApiRequest) =\u003e {\n    fetch(req.path.join('/'), {\n      method: req.method\n    })\n}\n````\n\n```ts\nimport * as z from \"zod-endpoints\";\n\nconst client: z.Api\u003ctypeof schema\u003e = {\n  \"GET_PROJECT\": (req) =\u003e http(req),\n  \"CREATE_PROJECT\": (req) =\u003e http(req)\n};\n```\n\n## Documentation\nZod endpoints is fully compatible with [open api specification](https://www.openapis.org/). The schema can be transformed into open api json. For example with Swagger this can be presented as a documentation website.\n\n```ts\nconst docs = z.openApi(schema)\n````\n![GitHub Logo](images/pets_swagger.png)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflock-community%2Fzod-endpoints","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflock-community%2Fzod-endpoints","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflock-community%2Fzod-endpoints/lists"}