or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

action-caching.mdcore-cache-operations.mdindex.mdnamed-caches.md
tile.json

tessl/maven-com-typesafe-play--play-cache-2-11

Cache API for Play Framework applications providing both synchronous and asynchronous cache operations

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/com.typesafe.play/play-cache_2.11@2.7.x

To install, run

npx @tessl/cli install tessl/maven-com-typesafe-play--play-cache-2-11@2.7.0

index.mddocs/

Play Framework Cache API

The Play Framework Cache API provides a comprehensive caching abstraction layer for Play Framework applications. It offers both synchronous and asynchronous APIs for cache operations with support for various cache implementations (EhCache, Caffeine, JCache). The library supports both Scala and Java programming languages with type-safe operations and configurable expiration times.

Package Information

  • Package Name: com.typesafe.play:play-cache_2.11
  • Package Type: Maven
  • Language: Scala/Java (dual language support)
  • Version: 2.7.9
  • Installation: Add libraryDependencies += "com.typesafe.play" %% "play-cache" % "2.7.9" to your build.sbt (requires Play Framework 2.7.x)

Core Imports

Scala API

import play.api.cache.{AsyncCacheApi, SyncCacheApi, Cached}
import javax.inject.Inject
import scala.concurrent.duration._

Java API

import play.cache.AsyncCacheApi;
import play.cache.SyncCacheApi;
import play.cache.Cached;
import play.cache.NamedCache;
import javax.inject.Inject;

Basic Usage

Scala Example

import play.api.cache.{AsyncCacheApi, SyncCacheApi}
import javax.inject.Inject
import scala.concurrent.Future
import scala.concurrent.duration._

class UserService @Inject()(cache: AsyncCacheApi) {
  // Async cache operations
  def getUser(id: String): Future[Option[User]] = {
    cache.get[User](s"user:$id").flatMap {
      case Some(user) => Future.successful(Some(user))
      case None => 
        // Load from database and cache
        loadUserFromDb(id).map { user =>
          cache.set(s"user:$id", user, 1.hour)
          Some(user)
        }
    }
  }
  
  // Sync cache operations
  def getUserSync(id: String): Option[User] = {
    cache.sync.get[User](s"user:$id") match {
      case Some(user) => Some(user)
      case None =>
        val user = loadUserFromDbSync(id)
        cache.sync.set(s"user:$id", user, 1.hour)
        Some(user)
    }
  }
}

Java Example

import play.cache.AsyncCacheApi;
import play.cache.SyncCacheApi;
import javax.inject.Inject;
import java.util.concurrent.CompletionStage;
import java.util.Optional;

public class UserService {
    private final AsyncCacheApi cache;
    
    @Inject
    public UserService(AsyncCacheApi cache) {
        this.cache = cache;
    }
    
    // Async cache operations
    public CompletionStage<Optional<User>> getUser(String id) {
        return cache.getOptional("user:" + id)
            .thenCompose(userOpt -> {
                if (userOpt.isPresent()) {
                    return CompletableFuture.completedFuture(userOpt);
                } else {
                    return loadUserFromDb(id)
                        .thenCompose(user -> 
                            cache.set("user:" + id, user, 3600)
                                .thenApply(done -> Optional.of(user))
                        );
                }
            });
    }
    
    // Sync cache operations
    public Optional<User> getUserSync(String id) {
        Optional<User> cached = cache.sync().getOptional("user:" + id);
        if (cached.isPresent()) {
            return cached;
        }
        
        User user = loadUserFromDbSync(id);
        cache.sync().set("user:" + id, user, 3600);
        return Optional.of(user);
    }
}

Architecture

The Play Cache API is organized around several key components:

  • Async/Sync API Pattern: Both AsyncCacheApi and SyncCacheApi provide similar operations, with sync APIs wrapping async APIs using blocking calls
  • Cross-Language Support: Scala and Java APIs with adapter classes for interoperability
  • Dependency Injection: Full integration with Play's DI framework using @Inject and @NamedCache
  • Type Safety: Scala ClassTag and Java generics for compile-time type safety
  • Action-Level Caching: Built-in support for HTTP response caching with ETag and Expires headers
  • Serialization: Automatic serialization handling for cacheable objects
  • Multiple Cache Support: @NamedCache annotation for using multiple cache instances

Capabilities

Core Cache Operations

Basic cache operations for storing, retrieving, and removing data with optional expiration times.

// Scala API
trait AsyncCacheApi {
  def set(key: String, value: Any, expiration: Duration = Duration.Inf): Future[Done]
  def get[T: ClassTag](key: String): Future[Option[T]]
  def remove(key: String): Future[Done]
  def getOrElseUpdate[A: ClassTag](key: String, expiration: Duration = Duration.Inf)(orElse: => Future[A]): Future[A]
  def removeAll(): Future[Done]
  lazy val sync: SyncCacheApi
}

trait SyncCacheApi {
  def set(key: String, value: Any, expiration: Duration = Duration.Inf): Unit
  def get[T: ClassTag](key: String): Option[T]
  def remove(key: String): Unit
  def getOrElseUpdate[A: ClassTag](key: String, expiration: Duration = Duration.Inf)(orElse: => A): A
}
// Java API
public interface AsyncCacheApi {
  default SyncCacheApi sync();
  <T> CompletionStage<Optional<T>> getOptional(String key);
  <T> CompletionStage<T> getOrElseUpdate(String key, Callable<CompletionStage<T>> block, int expiration);
  <T> CompletionStage<T> getOrElseUpdate(String key, Callable<CompletionStage<T>> block);
  CompletionStage<Done> set(String key, Object value, int expiration);
  CompletionStage<Done> set(String key, Object value);
  CompletionStage<Done> remove(String key);
  CompletionStage<Done> removeAll();
}

public interface SyncCacheApi {
  <T> Optional<T> getOptional(String key);
  <T> T getOrElseUpdate(String key, Callable<T> block, int expiration);
  <T> T getOrElseUpdate(String key, Callable<T> block);
  void set(String key, Object value, int expiration);
  void set(String key, Object value);
  void remove(String key);
}

Core Cache Operations

Action-Level HTTP Caching

Built-in HTTP response caching for Play Framework actions with ETag and cache header support.

class Cached @Inject() (cache: AsyncCacheApi)(implicit materializer: Materializer) {
  def apply(key: RequestHeader => String, caching: PartialFunction[ResponseHeader, Duration]): CachedBuilder
  def apply(key: RequestHeader => String): CachedBuilder
  def apply(key: String): CachedBuilder
  def apply(key: RequestHeader => String, duration: Int): CachedBuilder
  def apply(key: RequestHeader => String, duration: Duration): CachedBuilder
}

final class CachedBuilder {
  def apply(action: EssentialAction): EssentialAction
  def build(action: EssentialAction): EssentialAction
  def includeStatus(status: Int): CachedBuilder
  def includeStatus(status: Int, duration: Duration): CachedBuilder
  def default(duration: Duration): CachedBuilder
  def compose(alternative: PartialFunction[ResponseHeader, Duration]): CachedBuilder
}
@With(CachedAction.class)
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Cached {
  String key();
  int duration() default 0;
}

public class CachedAction extends Action<Cached> {
  public CompletionStage<Result> call(Request req);
}

Action-Level HTTP Caching

Dependency Injection and Named Caches

Support for multiple cache instances using named cache injection with Play's DI framework.

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface NamedCache {
  String value();
}

public class NamedCacheImpl implements NamedCache, Serializable {
  public NamedCacheImpl(String value);
  public String value();
}
// Type alias in Scala package object
type NamedCache = play.cache.NamedCache

Dependency Injection and Named Caches

Types

// Scala types
import akka.Done
import scala.concurrent.Future
import scala.concurrent.duration.Duration
import scala.reflect.ClassTag
import play.api.mvc.{EssentialAction, RequestHeader, ResponseHeader, Result}

// Default implementation classes
class DefaultSyncCacheApi @Inject() (val cacheApi: AsyncCacheApi) extends SyncCacheApi

private[play] final class SerializableResult(constructorResult: Result) extends Externalizable
// Java types
import akka.Done;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.Callable;
import java.util.Optional;

// Default implementation classes
@Singleton
public class DefaultAsyncCacheApi implements AsyncCacheApi
public class DefaultSyncCacheApi implements SyncCacheApi  
public class SyncCacheApiAdapter implements SyncCacheApi