Skip to content

stringbean/sttp-scribe

Repository files navigation

sttp-scribe - sttp backend for ScribeJava

Build Status Codacy Grade Test Coverage Maven Central - Scala 2.12 Maven Central - Scala 2.13

A backend implementation for sttp that allows you to use ScribeJava as a backend. Now you can call OAuth endpoints using sttp!

Quickstart

Add sttp-scribe, sttp and Scribe to your project:

libraryDependencies ++= Seq(
  "software.purpledragon"         %% "sttp-scribe"      % <version>,
  "com.softwaremill.sttp.client"  %% "core"             % "2.3.0",
  "com.github.scribejava"         %  "scribejava-apis"  % "8.3.3",
)

Setup your Scribe service:

val service = new ServiceBuilder("api-key")
  .apiSecret("api-secret")
  .callback("http://www.example.com/oauth_callback/")
  .build(GitHubApi.instance())

Create a token provider:

val tokenProvider = new OAuth2TokenProvider() {
  private var currentToken: Option[OAuth2AccessToken] = None

  override def accessTokenForRequest: OAuth2AccessToken = {
    currentToken.getOrElse { 
      // fetch from DB or another source
    }
  }

  override def tokenRenewed(newToken: OAuth2AccessToken): Unit = {
    currentToken = Some(newToken)
    // persist token to DB
  }
}

Then create a ScribeOAuth20Backend and use sttp to make authenticated calls:

import software.purpledragon.sttp.scribe.MonadAdaptor.Implicits.identity

implicit val monadError: MonadError[Identity] = IdMonad
implicit val backend: SttpBackend[Identity, Nothing, NothingT] = 
  new ScribeOAuth20Backend(service, tokenProvider)

val response: Response = basicRequest
  .get(uri"https://api.github.com/users/octocat")
  .send()

The Scribe backend will take care of refreshing the access token when it expires and retrying the current API call.

Asynchronous Backend

Scribe provides an asynchronous NIO based implementation that can be used by switching the monad:

import software.purpledragon.sttp.scribe.MonadAdaptor.Implicits.future

implicit val ec: ExecutionContext = ExecutionContext.Implicits.global
implicit val monadError: MonadError[Future] = new FutureMonad()
implicit val backend: SttpBackend[Future, Nothing, NothingT] = 
  new ScribeOAuth20Backend(service, tokenProvider)

val response: Future[Response] = basicRequest
  .get(uri"https://api.github.com/users/octocat")
  .send()