Skip to content

Tinkoff/muffin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Muffin

Build

Mattermost v4 API client for Scala 3.

Getting started

  1. Add muffin to your project dependencies:
libraryDependencies += "ru.tinkoff" %% "muffin-core" % "latest version in badge"
  1. Choose your integrations and include them, for example circe, http4s, and sttp with AsyncHttpClientCatsBackend:
libraryDependencies += "ru.tinkoff" %% "muffin-circe-json-interop" % "latest version in badge"
libraryDependencies += "ru.tinkoff" %% "muffin-sttp-http-interop" % "latest version in badge"
libraryDependencies += "com.softwaremill.sttp.client3" %% "async-http-client-backend-cats" % "3.7.6"
  1. Full example
import java.time.{LocalDateTime, ZoneId}

import cats.effect.*
import sttp.client3.asynchttpclient.cats.AsyncHttpClientCatsBackend

import io.circe.*

import muffin.api.*
import muffin.model.*
import muffin.dsl.*
import muffin.interop.circe.codec
import muffin.interop.http.Http4sRoute

type Api = ApiClient[IO, Encoder, Decoder]

class SimpleCommandHandler(api: Api){
  def time(command: CommandAction): IO[AppResponse[Nothing]] = {
    api.postToChannel(command.channelId, LocalDateTime.now().toString.some).as(ok)
  }
}

object Application extends IOApp.Simple {
    for {
        backend      <- AsyncHttpClientCatsBackend[IO]()
        httpClient   <- SttpClient[Task, Task, Encoder, Decoder](backend)
        given ZoneId <- ZIO.succeed(ZoneId.systemDefault())
        cfg          = ClientConfig("base mattermost api url", "auth token", "bot name", "your service base url")
        apiClient    = ApiClient[IO, Encoder, Decoder](httpClient, cfg)(codec)
      
        handler = SimpleCommandHandler(apiClient)
      
        router <- handle(handler).command(_.time).in[Task, Task]
      
        _ <- EmberServerBuilder
          .default[IO]
          .withHost(ipv4"0.0.0.0")
          .withPort(port"8080")
          .withHttpApp(Router("/" -> Http4sRoute.routes(router, codec)).orNotFound)
          .build
          .allocated
          .never
    } yield ()
}

More examples here

Supported integrations

Json integrations

libraryDependencies += "ru.tinkoff" %% "muffin-circe-json-interop" % "latest version in badge"
import muffin.interop.circe.codec.given
libraryDependencies += "ru.tinkoff" %% "muffin-zio-json-interop" % "latest version in badge"
import muffin.interop.zio.codec.given

Http integrations

libraryDependencies += "ru.tinkoff" %% "muffin-http4s-http-interop" % "latest version in badge"
import cats.effect.IO

import muffin.interop.http.Http4sRoute

val router: Router[IO] = ???
val codec = ??? // Choose you codec in json integrations section

val server = EmberServerBuilder
  .default[IO]
  .withHost(ipv4"0.0.0.0")
  .withPort(port"8080")
  .withHttpApp(Router("/" -> Http4sRoute.routes(app, codec)).orNotFound)
  .build
libraryDependencies += "ru.tinkoff" %% "muffin-zio-http-interop" % "latest version in badge"
import zio.*

import muffin.interop.http.ZioServer
import muffin.interop.circe.codec

val router: Router[Task] = ???
val codec = ??? // Choose you codec in json integrations section

val client = ZioClient[Task, /* Supported json encoder */, /* Supported json decoder */](codec)


val server = Server.start(8080, ZioServer.routes(router, codec))
libraryDependencies += "ru.tinkoff" %% "muffin-sttp-http-interop" % "latest version in badge"
import java.time.ZoneId

import cats.effect.IO

import muffin.model.*

val client = SttpClient[IO, IO, /* Supported json encoder */, /* Supported json decoder */](backend, codec)

Copyright

Copyright the maintainers

Logos made by Midjourney