What name should gRPC messages have to avoid conflicts with internal classes? - protocol-buffers

I have a class Book and its information needs to be passed on gRPC.
message Book {
...
}
But if I use this name there will be conflicts between one class and the other. Is there a convention on this? What name for I use for the gRPC equivalents?

Any meaningful and consistent name will be fine. This problem is not specific to protobuf/gRPC. Often times, we will have an entity class called Book and the corresponding DTO (data transfer object) BookDto with more or less same fields. We add the Dto to the entity class name to create BookDto.
This protobuf messages are basically these DTOs. You can follow the same.
You can use the Book name and access via the qualified path to avoid the conflict. You know this and I hope you do not like it.
Is it really a Book object? It might be a BookSearchRequest to query some books and you might expect BookSearchResponse from your gRPC service.

Related

Does serialization of objects with same class but different packages cause an errors in Axon?

I read a blog post and there was a sentence like this
"In Axon, there are constraints that require the package structure of the Event classes to be identical.
So even the same class, if the package is different, an error can occur."
And for this reason, he recommends using a multi-module structure.
is that true? I'm looking at the references and trying to find something like this, but I can't.
This point is indeed true, #YongD.
Axon Framework, when serializing any of your objects, will store the serialized format and the type. The serialized format that's stored most often is a byte[] of either XML or JSON. Which of the two depends on whether you have configured the XStreamSerializer or the JacksonSerializer.
So next to the serialized data, we have the type. The type, by default, would be the fully qualified class name and an optional revision number. Without the fully qualified class name, the serializer wouldn't know how to deserialize your data back into the required format. The package name is part of the FQCN, having different package names for conceptually the same class might cause issues upon deserialization.
This is why in sample projects provided by AxonIQ, you will always see all the messages belong to a core-api or api package or module. Already having this separation will allow for easier extraction of services into microservices at a later stage.

Where it is necessary to keep the DTO object when interacting with several services

A little background of my problem. I have a set of the following services:
AdapterService - intended for loading certain products from an external system
ApiGateway - accepts requests from UI. In particular, now there is only one request that receives product data to display product in UI from Product Service
ProductService - data storage service for various products. The service itself does not specifically know what kind of product it specifically stores. All types of products are created dynamically by other services that are responsible for these products. Product data is stored as a key-value map (technically it is a json string in DB column)
There is a schema for service interations
So, services in BLUE zone are mine (they can be changed in any way). RED zone describes services of another team (they can't be changed).
Whats the problem
To load product from external system I want to use SpecialProductDto which will store product data. I can use some validation features like Spring annotations and so on. Then to load the product from Adapter Service to ProductService I must transform SpecialProductDto to Map<String, Object> because ProductSerivcie requires it via API.
When I would get product info for UI through ApiGateway, I will need to call ProductService api for getting product that return attribues in Map<String, Object> and then transform this data to some UIReponse which contains some part of product data (because I dont need all product information, just only name and price for example).
But I also want to use SpecialProductDto in my ApiGateway service, because it seems working with Map<String, Object> is error prone... I practically need to fetch data blindly from Map to construct UIResponse. And what if some attribute names will be changed? With Map I only will know it when the request would be made from UI but using special DTO I get such exception in compilation time.
Question
So, what is the best practiсe or maybe patterт should I use in such situation? At the moment I see the following solutions:
Duplicate DTOs in both AdapterService and ApiGateway services. So, any changes in one class must be supported in another
Use Map<String, Object> at my own peril and risk, hoping that nothing will change there
Share SpecialProductDTO between ApiGateway and AdapterSerivce in some separate library and service (seems to be antipattern because of sharing someting can make a lot of problems)
Сan anyone help?
In my opinion, there's nothing wrong on duplicating DTOs.
Also, there's nothing wrong on providing the DTO in a separate library to be imported on each project, you will only be sharing the ProductService's contract and that's it. It does not cause any tight coupling between the Api Gateway and the Adapter. If the contract changes, then it must be changed on all of it's consumers (api gateway and adapter), simple as that.
About using Maps: usually I don't recommend this, because, like you said, you will not be able to take advantages of the built-in Bean Validations that Spring (and other frameworks) provides, but not only that, you'll also, depending on the situation, be using lots of casts and type conversions, which is not good and can be prevented by using DTOs.
Also, be aware that a DTO, in my opinion, should not be named with the suffix of 'DTO'. That's because a name like SpecialProductDTO doesn't clearly states where this object is being used or should be used.
Instead, prefer a something like CreateSpecialProductRequest - this indicates that this object is used when creating a Special Product. Another example is CreateSpecialProductResponse which just represents the response (if needed) after a Special Product creation. Take a look at this StackOverflow answer: Java data transfer object naming convention?

Creational adapter

I have a lot of code like this
additional_params = {
date_issued: pending.present? ? pending.date_issued : Time.current,
gift_status: status,
date_played: status == "Opened" ? Chronic.parse("now") : (opened.present? ? opened.date_played : nil),
email_template: service&.email_template,
email_text: service&.email_text,
email_subject: service&.email_subject,
label: service&.label,
vendor_confirmation_code: service&.vendor_confirmation_code
}
SomeService.new(reward, employee: employee, **additional_params).create
The same pattern applies to many models and services.
What is the name of this pattern?
How to refactor the current solution?
Is there a gem to solve this kind of solution? Like draper or something else
To me, that looks a bit like a god object for every type of entity. You expect your service to take care of everything related to your entity. The entity itself just acts as a data container and isn't responsible for its data. That's called an anemic model.
First of all, you need to understand that there can be several representations of the same entity. You can have several different classes that represent a user. On the "List user" page, the class contains just a subset of the information, maybe combined with information from the account system (last login, login attempt etc). On the user registration page, you have another class as it's not valid to supply all information for the user.
Those classes are called data transfer objects. Their purpose is to provide the information required for a specific use case and to decouple the internal entity from the external API (i.e. the web page).
Once you have done that, your service classes will start to shrink and you need fewer custom parameters for every method call.
Now your service class has two responsibilities: To manage all entities and to be responsible for their business rules.
To solve that, you should start to only modify your entities through behaviors (methods) and never update the fields directly. When you do so, you will automatically move logic from your service class to your entity class.
Once that is done, your service classes will be even cleaner.
You can read about Domain Driven Design to get inspired (no need to use DDD, but get inspired by how the application layer is structured in it).
You can try the builder pattern. I am not familiar with a ruby gem, but you can find information here: https://en.wikipedia.org/wiki/Builder_pattern and https://en.wikipedia.org/wiki/Fluent_interface

Spring Data-Rest POST to sub-resource

Lets say I have the following structure:
#Entity
class Person extends AbstractPersistable<Long> {
String name
String surname
}
#Entity
class Task extends AbstractPersistable<Long> {
String description
#ManyToOne
Person person
}
If I follow proper HAL guidelines I'm not supposed to expose entity id's. Since I don't have a bi-directional relationship I cant PUT or PATCH to http://localhost:8080/persons.
Even if I did create the relation, I probably wouldn't want to first POST the Task to /tasks and then PUT to /persons, (mobile clients are going to kill me). But even then I don't have the Task ID even from the returned Entity so I can PUT to the Person entity. (I obviously can string parse but I don't think it's appropriate).
I probably wouldnt want to have a list of 1000 tasks in the Person entity either. So not exporting the Task entity is not really an option (and this means PATCH will not work)
So how am I supposed to associate the Person with the Task if I cannot get his id? What is the correct approach?
If you want to associate a Task with a Person you need the link to the person.
Lets say the person URI is http://localhost/persons/1
Then you could assign the person to a task by just passing that URI in the person attribute.
So a post to Task could look like this:
{
"description": "some text",
"person": "http://localhost/persons/1"
}
Spring-data-rest will lookup the person and take care of the rest.
In HAL Links are used to reference related resources not ids and a HAL entity should always return a Link to itself, which serves as its unique identifier.
If I'm not mistaken you can also annotate fields with DBRef and links should be generated for you.
If you want related resources to actually show up inline with data you'll have to draft a Projection. See more here:
Spring Boot REST Resource not showing linked objects (sets)
Last but not least - if you want Projections to also contain Links you'll have to make ResourceProcessor's for them, see here:
How to add links to Spring Data REST projections?

Decoupling a client from a product?

I was reading a so article on design patterns and Sudhakar Kalmari wrote, "Use the Factory Method pattern when there is a need to decouple a client from a particular product that it uses." I don't understand what this means. To my knowledge, coupling is the degree to which a method or class is hardcoded with other dependencies. I am assuming the client he is referring to is whatever method is calling it, but I don't know what he means when he uses the word 'product'.
Can someone explain this terminology and also explain what he is trying to communicate here?
At the start of the article he lists some distinct components that make up the design pattern; mainly they are the Factory Method, an Abstract Product, a Concrete Product, and the Client.
Use the Factory Method pattern when there is a need to decouple a client from a
particular product that it uses. Use the Factory Method to relieve a client of
responsibility for creating and configuring instances of a product.
The word "product" is referring to objects that are /produced/ by the Factory and used by the caller (client). The client could just create these objects directly, but it would be responsible for knowing the specific object type and implementation details (the "Concrete Product"), coupling the caller to that code.
To "relieve a client of [that] responsibility" we'll introduce an abstract class or interface (the "Abstract Product") that is implemented by each "Concrete Product". The factory method will return this abstract type, and the client will call the factory method to create the objects it needs. The client is now decoupled from any specific implementation and only needs to know about the abstract type (and its factory).
The factory method is "responsible for creating and configuring instances of a product". It knows about the various implementations of the abstract type, and can create and return any one of those implementations to the client. The caller does not need to care which "concrete product" it receives, only that its dealing with a given abstract type.
Using a factory method, we can change implementation details (adding or modifying "concrete products" to our factory) without needing to change the implementation of the client itself, and without coupling the client to "a particular product".

Resources