首页 > 解决方案 > 寻找与 quarkus 共享微服务之间接口的最佳方式

问题描述

我对微服务还是很陌生,并且有一些我现在无法解决的基本架构问题。我使用 Quarkus 框架和 quarkus-resteasy 和 quarkus-rest-client 等标准扩展来实现。

场景:

我有一个“持久性”服务示例,我想通过专用 Maven 项目中的 REST 调用从外部填充数据。

@Path("/api/persistence")
@Products(MediaType.APPLICATION_JSON)
public class Persistence{

    @Inject
    EntityManager entityManager;

    @POST
    @Transactional
    public Response create(PostDto postDto) {
        Post post = toPostMapper.toResource(postDto);
        entityManager.persist(post);
        return Response.ok(postDto).status(201).build();
    }
}

同时我想有一个微服务DataGenerator来生成相应的数据并将其传递给Persistence服务。

我的问题:API 共享

这两个服务都是作为 Maven 项目创建的。根据教程,我发现正确的方法是像这样在项目中声明一个接口(这里称为PersistenceApiDataGenerator

@Path("/api/persistence")
@Products(MediaType.APPLICATION_JSON)
@RegisterRestClient
public interface PersistenceApi {

    @POST
    @Transactional
    public Response create(PostDto post) ;
    
}

然后通过@Inject 将该接口集成到DataGenerator服务中,从而产生以下示例性服务。

@RequestScoped
@Path("/api/datagenerator")
@Products("application/json")
@Consumes("application/json")
public class DataGenerator{

    @Inject
    @RestClient
    PersistenceApi persistenceApi 
    
    @POST
    public void getPostExamplePostToPersistence() {
        PostDto post = new PostDto();
        post.setTitle("Find me in db in persistence-service")
        persistenceApi.create(post);
    }
}

我在端口 8181 上本地运行,并在项目PersistenceService中添加了以下条目,以便可以找到该服务。application.propertiesDataGenerator

furnace.collection.item.service.PersistenceApi/mp-rest/url=http://localhost:8181
furnace.collection.item.service.PersistenceApi/mp-rest/scope=javax.inject.Singleton

我发现在 my 中声明接口是“错误的” DataGenerator,因为此时我没有注意到Persistence服务提供的 api 何时更改。因此,可以想出将接口定位在Persistence服务中的想法,然后由我的具体Persistence实现来实现,并导致以下代码。

@Path("/api/persistence")
@Products(MediaType.APPLICATION_JSON)
@RegisterRestClient
public class PersistenceApiImpl implements PersistenceApi {

    @Inject
    EntityManager entityManager;

    @POST
    @Transactional
    public Response create(PostDto fruit) {
        Post post = toPostMapper.toResource(fruit);
        entityManager.persist(post);
        return Response.ok(fruit).status(201).build();
    }

}

为了在我的DataGenerator项目中使用它们,我必须将Persistence项目作为依赖项包含在我的DataGenerator项目中,这对我来说听起来像是“带有额外步骤的整体”,因此在“关注点分离”方面感觉不对。

我尝试了以下方法: 我创建了另一个名为的 Maven 项目PersistenceApi,它只包含相应的PersistenceApi. 该PersistenceApi项目随后作为依赖项包含在“Persistence”和“DataGenerator”项目中。在“持久性”项目中,我实现了上面示例中的服务,并尝试通过@Inject.

不幸的是,这不起作用。在构建服务时,我收到一条消息PersistenceApi,即我想@InjectDataGenerator服务中包含的所需依赖项不能以UnsatisfiedResolutionException.

现在我的问题:

  1. 我看不出我在这里缺少什么。你可以帮帮我吗?
  2. 这种与专用 API 项目共享 API 的方式是可行的方式,还是“带有额外步骤的单体”方式真的可行?

先感谢您。

标签: javamavenquarkusquarkus-rest-client

解决方案


这是微服务的常见问题。就像在 Eberhard Wolff 的“微服务:Grundlagen flexibler Softwarearchitekturen”一书中(我看到你也是德国人)我遵循这样的想法,即微服务应该像开发它们的团队一样具有相同的耦合,就像你开发它的组织一样(有一个看看康威定律)。因此,大多数独立团队的服务应该独立开发,并且在更新时一个服务的 api 更改不应影响另一个服务。

如果您在您的团队中开发这两种服务,那么我认为您可以按照您的方式将它们结合起来,因为您不必与其他团队一起工作并且不会有巨大的开销。请注意,您将被迫同时发布这两个服务。如果这对您来说总是可以的,那么节省您的时间并按照自己的方式去做,如果不看看 API-Versioning:

我使用 api 版本控制,所以旧的 api 在“v1/”下仍然可以访问,而新的 api 在“v2/”下仍然可以访问。这样,其他微服务背后的团队就有足够的时间来更新他们的服务。

查看领域驱动设计,了解集成有界上下文(=服务)和耦合后果的不同方式。如果没有 API 版本控制,您将被迫建立合作伙伴关系,并且您需要一起发布。也许您更喜欢客户供应商甚至墨守成规。

要测试两种服务之间的兼容性,请查看消费者驱动的合同和Pact。您还可以生成打开的 api 文件并跟踪它们的更改,但这只会有助于通知人们有关更改。


推荐阅读