I'm trying to create an SDK for the discosWeb API.
Ostensibly, this seems to follow the JSON API standard. For example, here's a sample bit of data for a space-borne object:
{
"data": [
{
"type": "object",
"attributes": {
"shape": "Cyl",
"height": 28.0,
"xSectAvg": 59.8316320876176,
"xSectMax": 72.9933461154505,
"name": "Sputnik (8K71PS) Blok-A",
"cosparId": "1957-001A",
"depth": 28.0,
"satno": 1,
"xSectMin": 5.30929158456675,
"objectClass": "Rocket Body",
"length": 2.6,
"vimpelId": null,
"mass": 3964.32
},
"relationships": {
"states": {
"links": {
"self": "/api/objects/1/relationships/states",
"related": "/api/objects/1/states"
}
},
"destinationOrbits": {
"links": {
"self": "/api/objects/1/relationships/destination-orbits",
"related": "/api/objects/1/destination-orbits"
}
},
"launch": {
"links": {
"self": "/api/objects/1/relationships/launch",
"related": "/api/objects/1/launch"
}
},
"initialOrbits": {
"links": {
"self": "/api/objects/1/relationships/initial-orbits",
"related": "/api/objects/1/initial-orbits"
}
},
"operators": {
"links": {
"self": "/api/objects/1/relationships/operators",
"related": "/api/objects/1/operators"
}
},
"reentry": {
"links": {
"self": "/api/objects/1/relationships/reentry",
"related": "/api/objects/1/reentry"
}
}
},
"id": "1",
"links": {
"self": "/api/objects/1"
}
}
],
"links": {
"self": "/api/objects?page%5Bsize%5D=1",
"first": "/api/objects?page%5Bsize%5D=1&page%5Bnumber%5D=1",
"last": "/api/objects?page%5Bsize%5D=1&page%5Bnumber%5D=61384",
"next": "/api/objects?page%5Bsize%5D=1&page%5Bnumber%5D=2",
"prev": null
},
"meta": {
"pagination": {
"totalPages": 61384,
"currentPage": 1,
"pageSize": 1
}
}
}
Deserialising this data is obviously not as simple as it would be for a simple REST API that just returned nice POCOs with all the data we need. So, I'm trying to find a library that can do this part of the heavy lifting for me.
I was looking at this list of implementations and I'm trying to give this Hypermedia library a go.
Unfortunately, the documentation is a bit sparse... But following along with the quick-start, I've got this class (and some others) as one of my objects.
public record DiscosObject : DiscosModelBase
{
public int Id { get; init; }
public string? CosparId { get; init; }
public string? VimpelId { get; init; }
public int? SatNo { get; init; }
public string? Shape { get; init; }
public float? Mass { get; init; }
public float? Length { get; init; }
public float? Height { get; init; }
public float? Depth { get; init; }
public double CrossSectionMaximum { get; init; }
public double CrossSectionMinimum { get; init; }
public double CrossSectionAverage { get; init; }
public ObjectClass? ObjectClass { get; init; }
public Reentry Reentry { get; init; }
public IReadOnlyCollection<Country> States { get; init; }
public IReadOnlyCollection<OrbitDetails> DestinationOrbits { get; init; }
public IReadOnlyCollection<OrbitDetails> InitialOrbits { get; init; }
public IReadOnlyCollection<Organisation> Operators { get; init; }
}
So I'm trying to create my Builder()
for it like so:
builder.With<DiscosObject>("object")
.Id(nameof(DiscosObject.Id))
.HasMany<Country>("states")
.Template("/api/objects/{id}/states", nameof(DiscosObject.Id), res =>res.Id)
.HasMany<OrbitDetails>("initial-orbits"))
.Template("/api/objects/{id}/relationships/destination-orbits", nameof(DiscosObject.Id), res =>res.Id)
.HasMany<OrbitDetails>("destination-orbits"))
//etc...
But the relationship modelling here is confusing me. We have With()
, BelongsTo()
and HasMany()
. However, it's not obvious to me when we need a With()
and how you can model a many-many relationship here.
For instance, the ISS has many states Russia, USA, EU, etc. and each of those states has many Objects but there's no BelongsToMany()
option. I'm not sure if this is a limitation of the framework or a limitation of my understanding.
Does anyone have any experience with this library and know where I'm going wrong or know of an easier way to do this?
With
is used to define an object, whereas HasMany
and BelongsTo
are used to define relationships beteween objects.
A Many-to-Many relationship is really just a HasMany
that exists on both objects.