以一个官方的例子,开启lagom的学习之旅。
1: git clone https://github.com/lagom/activator-lagom-java-chirper.git。
2: 下载后进入目录,运行mvn lagom:runAll。
3: 浏览器输入:localhost:9000
4: 模块:
Chirp service: 负责存储聊天,提供存储接口服务。
Friend service: 负责用户存储,管理朋友关系。
Activity Stream service: 为聊天提供流数据的支持,依赖于 Chirp与Friend 服务。
Front-End service: 提供前台用户UI。
5:
- An
api
project: that contains a service interface through which consumers can interact with the service. - An
impl
project: that contains the service implementation.
ActivityStreamService.java
/* * Copyright (C) 2016 Lightbend Inc. <http://www.lightbend.com> */ package sample.chirper.activity.api; import sample.chirper.chirp.api.Chirp; import akka.stream.javadsl.Source; import akka.NotUsed; import com.lightbend.lagom.javadsl.api.ServiceCall; import com.lightbend.lagom.javadsl.api.Descriptor; import com.lightbend.lagom.javadsl.api.Service; import static com.lightbend.lagom.javadsl.api.Service.*; public interface ActivityStreamService extends Service { ServiceCall<NotUsed, Source<Chirp, ?>> getLiveActivityStream(String userId); ServiceCall<NotUsed, Source<Chirp, ?>> getHistoricalActivityStream(String userId); @Override default Descriptor descriptor() { // @formatter:off return named("activityservice").withCalls( pathCall("/api/activity/:userId/live", this::getLiveActivityStream), pathCall("/api/activity/:userId/history", this::getHistoricalActivityStream) ).withAutoAcl(true); // @formatter:on } }
Service interface (ActivityStreamService.java):
- 这个自定义的服务继承自 Service, 并且提供了一个Service.descriptor方法的实现。
Service.descriptor
返回Descriptor,定义了服务的名称,并且定义了提供的REST API。
- 提供了两个接口:getLiveActivityStream / getHistoricalActivityStream
- 关于 Service descriptor详细信息,https://www.lagomframework.com/documentation/1.4.x/java/ServiceDescriptors.html
Service implementation(ActivityStreamServiceImpl.java)
提供了对ActivityStreamService.java的实现
/* * Copyright (C) 2016 Lightbend Inc. <http://www.lightbend.com> */ package sample.chirper.activity.impl; import akka.NotUsed; import com.lightbend.lagom.javadsl.api.ServiceCall; import java.time.Duration; import java.time.Instant; import java.util.concurrent.CompletionStage; import javax.inject.Inject; import org.pcollections.PSequence; import sample.chirper.activity.api.ActivityStreamService; import sample.chirper.chirp.api.Chirp; import sample.chirper.chirp.api.ChirpService; import sample.chirper.chirp.api.HistoricalChirpsRequest; import sample.chirper.chirp.api.LiveChirpsRequest; import sample.chirper.friend.api.FriendService; import akka.stream.javadsl.Source; public class ActivityStreamServiceImpl implements ActivityStreamService { private final FriendService friendService; private final ChirpService chirpService; @Inject public ActivityStreamServiceImpl(FriendService friendService, ChirpService chirpService) { this.friendService = friendService; this.chirpService = chirpService; } @Override public ServiceCall<NotUsed, Source<Chirp, ?>> getLiveActivityStream(String userId) { return req -> { return friendService.getUser(userId).invoke().thenCompose(user -> { PSequence<String> userIds = user.friends.plus(userId); LiveChirpsRequest chirpsReq = new LiveChirpsRequest(userIds); // Note that this stream will not include changes to friend associates, // e.g. adding a new friend. CompletionStage<Source<Chirp, ?>> result = chirpService.getLiveChirps().invoke(chirpsReq); return result; }); }; } @Override public ServiceCall<NotUsed, Source<Chirp, ?>> getHistoricalActivityStream(String userId) { return req -> friendService.getUser(userId).invoke().thenCompose(user -> { PSequence<String> userIds = user.friends.plus(userId); // FIXME we should use HistoricalActivityStreamReq request parameter Instant fromTime = Instant.now().minus(Duration.ofDays(7)); HistoricalChirpsRequest chirpsReq = new HistoricalChirpsRequest(fromTime, userIds); CompletionStage<Source<Chirp, ?>> result = chirpService.getHistoricalChirps().invoke(chirpsReq); return result; }); } }