Model an overview object in an object oriented way - oop

I have an api that displays, let's say, cities:
/cities
/city/{id}
The cities endpoint returns an overview of the city (id, city name, city area), whereas the city endpoint returns the same plus some more (population, image, thumbnail...). Now, when modelling this in the client I see different alternatives:
Have a CityOverview class which has a City subclass that adds the extra attributes.
Have a City class that has all the attributes with a CityOverview subclass that hides all the extra attributes (say, in Java, by throwing an UnsupportedOperationException on all the getters for attributes it doesn't have).
Have the above classes with no inheritance relationship.
Have a single City class that allows all the extra attributes to be nulled.
What are the pros and cons of the above approaces and/or any other you can think of?

I would go with option 3 - have 2 classes ,i.e. not an inheritance relationship. Here are the reasons for this decisions -
You will need to de-serialize\serialize JSON using an api such as jackson. For this you will need a field mapped POJO. Since, you have 2 separate classes now, you can map different POJOs to the 2 different api calls. It makes the code cleaner.
Inheritance is not an option because of 2 reasons - 1).At one time any of your API calls will either bring data for parent or child. I.e. the fields of either will always be empty depending on which API call you make. This is an unnecessary waste.
2). From an OOP design point-of-view the data object being returned in cities call is not a parent of the data being returned in the city{id} call. So, we should not have this in the class design as well. They together make up the "City" entity.

I think that if there is not a big difference between the OverviewCity and the City You should only keep a single City class in the BE.
In your /cities api your can pass the full list of your cities.
Displaying a list of cities with a few details on each city (OverviewCity) can be created easily from a City object by the client side.
In the Backend I dont think there is any need to support 2 classes.

Related

RESTful Endpoint that returns single entity by two different unique parameters but not both at the same time

I want to understand what would be the best way to represent this in a RESTful way, taking in consideration that the codebase it's a very large - inherited - legacy project and I have to add a lot of new functionality on top of it.
The API Definition is built with OpenaAPI3.
Let's take in consideration the following example:
/v1/{customer}/types/{id}
But the Types collection also has a database constraint of Unique(customer, code) - customer and code being columns from the Types table.
What I need to implement now is a new endpoint that will retrieve a single entity, based on the customer path param and code path param, without having to use the ID path param.
It's a matter of reducing the number of calls, that's why I don't want to make use of the ID path param also.
One solution would be to use query params:
/v1/{customer}/types?code=123
But this will basicaly return a Singleton List so it's not that trivial and definetley not a best practice.
What would be your take on this? I know I should have the ID in the place I want that entity to be returned, but this some case I want to get resovled without having to do another call to get the ID of the entity so I can call the initial endpoint.

O.O.P and Class Properties

I'm new to O.O.P and would like advice on best practice.
Say for example I have a Course class which holds course information, and a Location class which holds location details. Classes have corresponding repository classes. Now, each Course HAS A location which I have added Location as a property.
When I am pulling the details of a Course from the database, is it best practice to:
A – Populate the Location object from within the CourseRepository Class meaning SQL would return both course and location details
B – Only populate Course object, returning the Location ID, then use the LocationRepository class to find the location details
I’m leaning more towards B as this is a separation of responsibility, however, the thing that’s getting me is performance. Say I need a List instead which returns a result of 50. Would it be wise to query SQL 50 times to seek location details? Would appreciate your thoughts on this.
Lewis
In part, you're thinking in a wrong conceptual direction. It should be: one location can have many courses, not the reciprocal.
That said, theoretical, a Course domain object should not contain a location as class member, but just a location id. On the other hand, a domain object Location could contain an array of Course objects as class member, if needed. You see the difference?
Now, in your case, indeed pass a Location as argument to a Course object. And, in the Course repository, define a method like fetchCoursesWithLocations() in which you run only one sql query to fetch 50 courses TOGETHER WITH the corresponding location details - based on your criterias - into an array. Then loop through the records array. For each of the record item build a Location object and a Course object (to which you pass the Location object as argument). Then pass each so created Course object to another array holding all resulting Course objects, or to a CourseCollection object (which I recommend). In the end return the Courses array (or the CourseCollection content) from the method.
Now, all is somehow too complex to present in here. But I'll give you here three great articles (a serie) which will make the whole process very clear to you. You'll find out in there how a CourseCollection should see, too. In the articles (from the second one upwards), it is used the term "Mapper", which I'm pretty sure it's the same as your "repository". Actually, there are two abstraction layers for data access in the db: mappers and repositories. Plus the adapters.
Look to the part with the PostMapper and the CommentMapper. They are the parallels to your CourseRepository, respectively your LocationRepository. The same roles have Post and Comment models (domain objects!): as parallels to your Course and Location.
The articles are:
Building a Domain Model - An Introduction to Persistence
Agnosticism
Building a Domain Model - Integrating Data Mappers
Handling Collections of Aggregate Roots - the Repository Pattern

Work with dto's to build an API with DDD

I'm starting to work with dto's (data transfer objects) and I have some doubts about the best way to build the system architecture of the API.
Imagine a domain entity 'A', with relations to 'B', 'C' and 'D'. We have a service 'S' that return a json list with all "A's". It's correct to create an 'ADTO' in that service, fill with "BDTO's", "CDTO's" and "DDTO's"? If then we have another service "S2", and we need to return an specific set of "B's", then we need to create another tree of "B2DTO's" with "C2DTOS's", "D2DTO's"... ? Is this the correct way to do it?
I see that this way, we'll have a huge and complex tree of DTO's, with an specific DTO's for each use case.
EDIT:
I forgot the assemblers part. Is necessary to implement a different assembler for every DTO? for example, for an entity A, we have two DTO's. Can I use the same assembler or is better to have A1Assembler and A2Assembler?
Your DTOs should represent a set of data that you want your client to have. Usually, you should never 'copy' your entities into DTOs because you may have fields that you don't want to share with the world. Let's supposed that you are creating automatically a 'tracking' column with the ID of who entered that data, or say that you have a Customer entity with password fields. You don't want that to be part of your DTOs. That's why you must be EXTRA CAREFUL when using AutoMapper etc.
When you design DTOs think about what your client needs from that endpoint specifically. Sometimes DTOs may look the same and that's ok. Also, your DTOs can be as simple or as complex as needed. One crazy example, lets say that a page where you show an artist, his songs, the voting rate for those songs and some extra data.
If your use case justifies it, you may very well put all of that into a DTO. DTO all they do is carry data.
YES, your services should return DTOS (POCO).
Also, DTO is just naming convention. Don't get caught up in the "dto" suffix. A 'command' coming from a client is a DTO, but in that case you would call it AddNewCustomerCommand for example.
Makes sense?
I think you mistake what your DTO's are. You'll have 2 kind of DTO's Roughly speaking
1) they can be your domain entities, then you can return ADTO, BDTO and CDTO. But those DTO's can be fairly consistent (why would B2DTO be any different from BDTO)
If you look at what your json would look at
{
Id: 1
name: "foobar",
$type: "A",
B: [ {
name: "b-bar",
$type: "B"}]
CIds: [ 2,23, 42]
}
Here you see 2 kind of objects, some (B's) are returned in full in your DTO as subobjects. Others (like C) are turned by Id and can be queried separately. If it's S2 which implements the C query or not you don't care about.
2) When you get to an architecture like CQRS then you do get different DTO's. (projections or commands) but then you would also see this in the naming of the DTO's. Forexample are
AListOnOverviewPageDTO, AUserEditDetailDTO, etc.
Now it makes very much sense to have different DTO's since they are projections representing very different usecases. (and not a full object as is common in DDD)
Update The reason you want different DTO's are twofold. First of all it allows you to optimize each call separately. Maybe the list needs to be faster so (using CQRS) you can put the right indexes on your data so your listDTO will be returned faster. It allows you to reason about usecases more easily. Since each DTO represents 1 usecase/screen (Otherwise you get cases ok in the userlistDTO i need to populate only these 3 fields in this case ..etc.).
Furthermore you need to make sure you API is honest. NEVER EVER return a "age" field with empty data but have some other call return the same user but with another call return the same user with a real age. It makes your backend appear broken. However if i had a call to /users/list and another call to /users/1/detail it would be natural if the detail calls returned more fields about a specific user

Does OWL punning treats class and individual with same name as SAME semantically?

According to the original OWL definition of OWL DL, we can't give the same name to a class and an individual (which is a clear difference between OWL DL and OWL Full). "Punning" is introduced in OWL 2 and removes this restriction. So I can give same name to a class and an individual (and a property too).
Does OWL treat them as semantically the same or different? (Both have the same name, so they're syntactically the same.) Are these entities (having the same IRI) one and the same? [As in OWL everything is related to IRI only]
Does OWL treats them as semantically same or different ? (both are
having same IRI so syntactically same). In simple, do these entities
(having same IRI) one and the same ? [As in OWL everything is related
to IRI only]
From the documentation that you linked to (emphasis added):
2.4.1 F12: Punning
OWL 1 DL required a strict separation between the names of, e.g.,
classes and individuals. OWL 2 DL relaxes this separation somewhat to
allow different uses of the same term, e.g., Eagle, to be used for
both a class, the class of all Eagles, and an individual, the
individual representing the species Eagle belonging to the (meta)class
of all plant and animal species. However, OWL 2 DL still imposes
certain restrictions: it requires that a name cannot be used for both
a class and a datatype and that a name can only be used for one kind
of property. The OWL 2 Direct Semantics treats the different uses of
the same name as completely separate, as is required in DL reasoners.
When punning, you get to use the same name to refer to more than one thing;
the IRI is the same, but that's it; the things are still different. If you use the same IRI as an identifier for a class, and for an individuals, that's all you've done. There's a class that's named by that IRI, and there's an individuals that's named by that IRI; they're not the same thing, and can't be the same thing, because classes and individuals are different kinds of things.
For instance, if you have a class called x and an individual called x, then you can say things like
(the individual) x is related to individual y by object property p
or
the individual y is an element of (the class x)
You can't say, though,
the individual y is an element of (the individual) x [because individuals don't have elements, classes do]
or that
(the class) x is related to individual y by object property p [because object properties don't relate classes to individuals, they relate individuals to individuals]
IRIs are really just names in OWL, they're not entities in and of themselves. Punning in OWL lets you use the same name for multiple things when there's no confusion of mixing those things up. In the case of classes and individuals, they're different kinds of things, so you can reuse names, because the context will always make it clear which one you meant.

In UML/ER diagramming, how to notate & make transaction requirements with entity that has different values depending on a certain attribute?

I am diagramming an art museum system, where there are Permanent_Art_Objects. Each Permanent_Art_Object has many attributes, and can also be either a 1) Sculpture/Statue, 2) Painting, or 3) Other. Depending on whether it's a sculpture/statue, painting, or other, it has sub-attributes unique to itself.
Here is an example of these sub-attributes.
What is the proper notation for showing these 'sub-attributes'?
For example, if Permanent_Art_Object is Other, it has as sub-attributes Type and Style.
Also, how would I make a query to INSERT INTO Permanent_Art_Object VALUES() for a new art object, if there's so much variety??
It all depends on what you are making. If this is purely for a database, I think ERD's are the cleanest way for modeling but a sidenote is that there are atleast 4 types of notations. Below is how I would do it in UML and ERD with the limited context I have.
More info about ERD's:
Basics: http://web.cse.ohio-state.edu/~gurari/course/cse670/cse670Ch2.xht
Specialisations: http://web.cse.ohio-state.edu/~gurari/course/cse670/cse670Ch16.xht
Overview of different types: http://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model#Cardinalities
My example: