寻找在微服务与 quarkus 之间共享接口的最佳方式

Looking for the best way to share an interface between microservices with 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 项目创建的。 根据教程,我发现正确的方法是在 DataGenerator 项目中像这样声明一个接口(这里称为 PersistenceApi

@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 运行,并在 DataGenerator 项目的 application.properties 中添加了以下条目,以便可以找到该服务.

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

我发现在我的 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 项目中,这听起来像是一个“带有额外的步骤”对我来说因此在“关注点分离”方面感觉不对。

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

解决“DataGenerator”项目中的相应接口

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

现在我的问题:

  1. 我没有看到我在这里遗漏了什么。你能帮帮我吗?
  2. 这种 API 与专用 Api 项目共享的方式是否可行,或者“具有额外步骤的单体”方法真的可行吗?

提前致谢。

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

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

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

查看域驱动设计以了解 integrating bounded contexts(=服务)的不同方式和耦合结果。如果没有 API-版本控制,您将被迫建立伙伴关系并且需要一起发布。也许您更喜欢客户-供应商,甚至是循规蹈矩的人。

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