{"id":15159355,"url":"https://github.com/pheymann/typedapi","last_synced_at":"2025-05-02T12:31:04.789Z","repository":{"id":57722065,"uuid":"123158505","full_name":"pheymann/typedapi","owner":"pheymann","description":"Build your web API on the type level.","archived":false,"fork":false,"pushed_at":"2019-05-22T09:41:25.000Z","size":437,"stargazers_count":159,"open_issues_count":5,"forks_count":10,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-04-07T01:52:17.360Z","etag":null,"topics":["api","scala","servant","shapeless","typelevel","typesafe"],"latest_commit_sha":null,"homepage":"","language":"Scala","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/pheymann.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}},"created_at":"2018-02-27T16:43:21.000Z","updated_at":"2025-02-21T20:27:13.000Z","dependencies_parsed_at":"2022-08-29T22:31:44.225Z","dependency_job_id":null,"html_url":"https://github.com/pheymann/typedapi","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pheymann%2Ftypedapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pheymann%2Ftypedapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pheymann%2Ftypedapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pheymann%2Ftypedapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pheymann","download_url":"https://codeload.github.com/pheymann/typedapi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252038110,"owners_count":21684626,"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","scala","servant","shapeless","typelevel","typesafe"],"created_at":"2024-09-26T21:05:15.312Z","updated_at":"2025-05-02T12:31:04.033Z","avatar_url":"https://github.com/pheymann.png","language":"Scala","readme":"[![Build Status](https://travis-ci.org/pheymann/typedapi.svg?branch=master)](https://travis-ci.org/pheymann/typedapi)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.pheymann/typedapi-client_2.12/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.pheymann/typedapi-shared_2.12)\n[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/pheymann/Lobby)\n[![Scala.js](https://www.scala-js.org/assets/badges/scalajs-0.6.17.svg)](https://www.scala-js.org/)\n\n*experimental project*: see issues [#39](https://github.com/pheymann/typedapi/issues/39) and [#41](https://github.com/pheymann/typedapi/issues/41)\n\n# Typedapi\nDefine type safe APIs and let the Scala compiler do the rest:\n\n### Api definition\n```Scala\nimport typedapi._\n\nval MyApi =\n  // GET {body: User} /fetch/user?{name: String}\n  api(method = Get[MT.`application/json`, User], \n      path = Root / \"fetch\" / \"user\", \n      queries = Queries add Query[String]('name)) :|:\n  // POST {body: User} /create/user\n  apiWithBody(method = Post[MT.`application/json`, User], \n              body = ReqBody[Json, User], \n              path = Root / \"create\" / \"user\")\n```\n\nAnd for the Servant lovers:\n\n```Scala\nimport typedapi.dsl._\n\nval MyApi = \n  // GET {body: User} /fetch/user?{name: String}\n  (:= :\u003e \"fetch\" :\u003e \"user\" :\u003e Query[String]('name) :\u003e Get[MT.`application/json`, User]) :|:\n  // POST {body: User} /create/user\n  (:= :\u003e \"create\" :\u003e \"user\" :\u003e ReqBody[Json, User] :\u003e Post[MT.`application/json`, User])\n```\n\n### Client side\n```Scala\nimport typedapi.client._\n\nval (fetch, create) = deriveAll(MyApi)\n\nimport typedapi.client.http4s._; import cats.effect.IO; import org.http4s.client.blaze.Http1Client\n\nval cm = ClientManager(Http1Client[IO]().unsafeRunSync, \"http://my-host\", 8080)\n\nfetch(\"joe\").run[IO](cm): IO[User]\n```\n\n### Server side\n```Scala\nimport typedapi.server._\n\nval fetch: String =\u003e IO[Result[User]] = name =\u003e findUserIO(name).map(success)\nval create: User =\u003e IO[Result[User]] = user =\u003e createUserIO(user).map(success)\n\nval endpoints = deriveAll[IO](MyApi).from(fetch, create)\n\nimport typedapi.server.http4s._; import cats.effect.IO; import org.http4s.server.blaze.BlazeBuilder\n\nval sm     = ServerManager(BlazeBuilder[IO], \"http://my-host\", 8080)\nval server = mount(sm, endpoints)\n\nserver.unsafeRunSync()\n```\n\nThis is all you have to do to define an API with multiple endpoints and to create a working client and server for them.\n\nYou can find the above code as a complete project [here](https://github.com/pheymann/typedapi/tree/master/docs/example).\n\n## Motivation\nThis library is the result of the following questions:\n\n\u003e How much can we encode on the type level? Are we able to describe a whole API and generate the call functions from that without using Macros?\n\nIt is inspired by [Servant](https://github.com/haskell-servant/servant) and it provides an API layer which is independent of the underlying server/client implementation. Right now Typedapi supports:\n\n  - [http4s](https://github.com/http4s/http4s)\n  - [akka-http](https://github.com/akka/akka-http)\n  - [scalaj-http](https://github.com/scalaj/scalaj-http) on the client-side\n  - ScalaJS on the client-side\n\nIf you need something else take a look at this [doc](https://github.com/pheymann/typedapi/blob/master/docs/ExtendIt.md#write-your-own-client-backend).\n\n## Get this library\nIt is available for Scala 2.11, 2.12 and ScalaJS and can be downloaded as Maven artifact:\n\n```\n// dsl\n\"com.github.pheymann\" %% \"typedapi-client\" % \u003cversion\u003e\n\"com.github.pheymann\" %% \"typedapi-server\" % \u003cversion\u003e\n\n// http4s support\n\"com.github.pheymann\" %% \"typedapi-http4s-client\" % \u003cversion\u003e\n\"com.github.pheymann\" %% \"typedapi-http4s-server\" % \u003cversion\u003e\n\n// akka-http support\n\"com.github.pheymann\" %% \"typedapi-akka-http-client\" % \u003cversion\u003e\n\"com.github.pheymann\" %% \"typedapi-akka-http-server\" % \u003cversion\u003e\n\n// Scalaj-Http client support\n\"com.github.pheymann\" %% \"typedapi-scalaj-http-client\" % \u003cversion\u003e\n\n// ScalaJS client support\n\"com.github.pheymann\" %% \"typedapi-js-client\" % \u003cversion\u003e\n```\n\nYou can also build it on your machine:\n\n```\ngit clone https://github.com/pheymann/typedapi.git\ncd typedapi\nsbt \"+ publishLocal\"\n```\n\n## Ammonite\nTypedapi also offers an improved experience for [Ammonite](http://ammonite.io/#Ammonite-REPL) and [ScalaScripts](http://ammonite.io/#ScalaScripts):\n\n```Scala\nimport $ivy.`com.github.pheymann::typedapi-ammonite-client:\u003cversion\u003e`\n\nimport typedapi._\nimport client._\nimport amm._\n\nval Readme = api(Get[MT.`text/html`, String], Root / \"pheymann\" / \"typedapi\" / \"master\" / \"README.md\")\nval readme = derive(Readme)\n\n// gives you the raw scalaj-http response\nval cm = clientManager(\"https://raw.githubusercontent.com\")\nval response = get().run[Id].raw(cm)\n\nresponse.body\nresponse.headers\n...\n```\n\nIn case Ammonite cannot resolve `com.dwijnand:sbt-compat:1.0.0`, follow [this](https://github.com/pheymann/typedapi/blob/master/docs/ClientCreation.md#ammonite) solution.\n\n## Documentation\nThe documentation is located in [docs](https://github.com/pheymann/typedapi/blob/master/docs) and covers the following topics so far:\n - [How to define an API](https://github.com/pheymann/typedapi/blob/master/docs/ApiDefinition.md)\n - [How to create a client](https://github.com/pheymann/typedapi/blob/master/docs/ClientCreation.md)\n - [How to create a server](https://github.com/pheymann/typedapi/blob/master/docs/ServerCreation.md)\n - [Extend the library](https://github.com/pheymann/typedapi/blob/master/docs/ExtendIt.md)\n - Typelevel Summit 2018 Berlin Talk [Typedapi: Define your API on the type-level](https://github.com/pheymann/typelevel-summit-2018)\n - and a [post](https://typelevel.org/blog/2018/06/15/typedapi.html) on the Typelevel Blog describing the basic concept behind this library.\n\n## Dependencies\n - [shapeless 2.3.3](https://github.com/milessabin/shapeless/)\n\n## Contribution\nContributions are highly appreciated. If you find a bug or you are missing the support for a specific client/server library consider opening a PR with your solution.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpheymann%2Ftypedapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpheymann%2Ftypedapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpheymann%2Ftypedapi/lists"}