寻找在微服务与 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”项目中的相应接口
不幸的是,这不起作用。当我构建服务时,我收到一条消息,我想通过 @Inject
在 DataGenerator
服务中包含所需的依赖项 PersistenceApi
,不能以UnsatisfiedResolutionException
.
现在我的问题:
- 我没有看到我在这里遗漏了什么。你能帮帮我吗?
- 这种 API 与专用 Api 项目共享的方式是否可行,或者“具有额外步骤的单体”方法真的可行吗?
提前致谢。
这是微服务的一个常见问题。就像 Eberhard Wolff 在“微服务:Grundlagen flexer Softwarearchitekturen”一书中一样(我看到你也是德国人)我遵循这样的想法,即微服务应该像开发它们的团队一样具有相同的耦合,并且像你开发它的组织一样(有一个看看 Conway's law)。因此,大多数独立团队的服务应该独立开发,一个服务的api更改在更新时不应影响另一个服务。
如果你在你的团队中开发这两种服务,那么我认为你可以按照你正在做的方式将它们结合起来,因为你不必与其他团队一起工作并且不会有巨大的开销。 请注意,您将被迫同时发布这两项服务。 如果这对您来说总是可以的,那么请节省您的时间并按您的方式进行,如果不行,请查看 API -版本控制:
我使用 api 版本控制,所以旧的 api 仍然可以在“v1/”下访问,新的可以在“v2/”下访问。这样其他微服务背后的团队就有足够的时间来更新他们的服务。
查看域驱动设计以了解 integrating bounded contexts(=服务)的不同方式和耦合结果。如果没有 API-版本控制,您将被迫建立伙伴关系并且需要一起发布。也许您更喜欢客户-供应商,甚至是循规蹈矩的人。
要测试两种服务之间的兼容性,请查看消费者驱动的合同和 Pact。您还可以生成打开的 api 文件并跟踪它们的更改,但这只会帮助通知人们有关更改的信息。
我对微服务还很陌生,有一些我现在无法解决的基本架构问题。 我正在使用 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
.
不幸的是,这不起作用。当我构建服务时,我收到一条消息,我想通过 @Inject
在 DataGenerator
服务中包含所需的依赖项 PersistenceApi
,不能以UnsatisfiedResolutionException
.
现在我的问题:
- 我没有看到我在这里遗漏了什么。你能帮帮我吗?
- 这种 API 与专用 Api 项目共享的方式是否可行,或者“具有额外步骤的单体”方法真的可行吗?
提前致谢。
这是微服务的一个常见问题。就像 Eberhard Wolff 在“微服务:Grundlagen flexer Softwarearchitekturen”一书中一样(我看到你也是德国人)我遵循这样的想法,即微服务应该像开发它们的团队一样具有相同的耦合,并且像你开发它的组织一样(有一个看看 Conway's law)。因此,大多数独立团队的服务应该独立开发,一个服务的api更改在更新时不应影响另一个服务。
如果你在你的团队中开发这两种服务,那么我认为你可以按照你正在做的方式将它们结合起来,因为你不必与其他团队一起工作并且不会有巨大的开销。 请注意,您将被迫同时发布这两项服务。 如果这对您来说总是可以的,那么请节省您的时间并按您的方式进行,如果不行,请查看 API -版本控制:
我使用 api 版本控制,所以旧的 api 仍然可以在“v1/”下访问,新的可以在“v2/”下访问。这样其他微服务背后的团队就有足够的时间来更新他们的服务。
查看域驱动设计以了解 integrating bounded contexts(=服务)的不同方式和耦合结果。如果没有 API-版本控制,您将被迫建立伙伴关系并且需要一起发布。也许您更喜欢客户-供应商,甚至是循规蹈矩的人。
要测试两种服务之间的兼容性,请查看消费者驱动的合同和 Pact。您还可以生成打开的 api 文件并跟踪它们的更改,但这只会帮助通知人们有关更改的信息。