Just discovered this <https://jsonapi.org/format/#...
# cfml-general
a
Just discovered this https://jsonapi.org/format/#document-top-level - anyone used it and have opinions?
r
That's useful, thank you for sharing this.
a
just starting to explore it myself so can't say good or bad yet but nice to have some kind of standard!
d
I have consumed an API that I think may conformed to that standard. It definitely creates odd objects when you start getting complicated systems. I never saw the "standard" written so it was always guess or check for us.
Personally I would have to see who is backing that standard, what standardized tooling is being made to make using the standard easy to use (point of a standard in my opinion) and what is the basis on why the verbosity that it appears to want to impart on the json. (I haven't read the standard yet so some of this may be explained in the link. Just my thoughts on when to adopt "random" standards that are not considered industry)
๐Ÿ‘๐Ÿผ 1
s
We looked into it a while back and there were a couple big discussions of it here. My takeaway was that you need to have standardization have a whole lot of value in your project, e.g. multiple stakeholders and lots of complex data, because otherwise it's over-engineered
๐Ÿ‘๐Ÿผ 1
It does solve some of the inherent issues with REST though
But we had to make 100+ API endpoints in a year and that was going to add a lot of development time for very little payoff in our case
d
4.2 and 4.1 are red flags to me. Using non standard content-types is a bit sus for me.
a
We started off with the intention of doing REST but quickly hit limits with it and now have a ball-of-mud. GraphQL isn't an option in CFML land so this looked promising. Seems it's part of Drupal for what that's worth.
Do you have an internal spec your APIs confirm to then @sknowlton?
s
We use a modified version of the Ortus generic API response object, which is way simpler than anything JSONAPI is trying to do. It starts turning into a ball of mud when we get resources that are combinations of things -- for instance, we do youth sports, and we have a 'player' (a person with a name/dob/gender/etc) and we have 'a registration' (that player's presence in a particular season of play) and nine times out of ten, somebody wants a combination of both of those things. We've "solved" this in some cases by using fancy combinations of schemas with the OpenAPI spec where we can do unions or intersections of different files but it very much falls on the 'powerful but disorganized' side of the spectrum. We can do whatever we want without many constraints but we do sometimes solve the same thing three different ways because no one person has a super great view of the whole API. But...that's also an honest reflection of the business. ๐Ÿ™‚
I think it's the least bad way forward because the barrier to entry is low. It's easy to write, easy to consume, and if there are some inconsistencies between what a "player" looks like on this endpoint versus that endpoint....meh, not the end of the world.
a
Thanks - appreciate your thoughts / experience
Looks like the Ortus response is similar. The
data
is much simpler though. https://coldbox.ortusbooks.com/digging-deeper/recipes/building-rest-apis#overview
s
Yeah, it's trying to slay way fewer dragons than JSONAPI
๐Ÿ‘ 1
d
I was recently looking into the whole GraphQL thing and wondered why GraphQL isnโ€™t an option in cfml as @aliaspooryorik points out - is it a technical limitation of cfml or just not enough people in cfml to get something up and running? Is there a java graphql engine that could be proxied?
s
I thought Eric at Ortus had a module for GraphQL but maybe it was just a prototype. I know he played with it a bit but don't see anything on Forgebox
a
Eric has a module for everything - even making Pizza
d
I currently use taffy which is great but end up with lots of REST endpoints. I originally started building a version of our API using jsonapi but it quickly became bloated and more complicated than I felt it needed to be.
I would love a cfml graphql option.
r
I use ColdBox for my APIs and love it because it is versatile, and depending on how you want to structure your endpoints, it can cut down a ton on endpoints by grouping related data. It works for simple and complex APIs, versioning by modules. So, it is easier for me to understand one framework that can handle complexities, but I can still just as easily create a simple API with it as well.
j
We're using Taffy as the framework but the response is based on the jsonapi spec, although not strictly. One of the things I like is being able to include related data which would otherwise require multiple requests
d
"graphQL isn't an option" doesn't make sense to me. It is just a different client api to your internal workings. You could use the java libraries if you needed to. The question comes down to who is consuming your data and why you want it to be sparkly clean? If you are just doing internal apis then just use your own standard and make your own contracts. If you are creating and selling an api, then using a spec makes sense. It all comes down to how much work you want to put into it and 90% of the time internal api don't need that much thought.
a
It's an internal API - but it's a wild-west currently (the oldest code is "remote" methods)! If I can find some kind of vaguely sensible spec then I can just say "do this" and not get bogged down in the personal preferences of each developer (same goes for code formatting so just saying "ortus cfformat rules" ends the internal bickering!)
Ultimately it seems to me that having an object with the data it it which then transforms to whatever our spec is is the way to go. Currently it's just
serializeJSON(randomstuff)
so that could be arrays, booleans, structs whatever with no guaranteed keys or format.
Which loops back to using a generic API response object which produces consistent JSON results.
d
Yea we have a siimple spec of get requests with lists comback as an object with the key of the items you pulled, and everything else comes back as the struct it has. Error reporting/handling is done via the headers/statuscodes.
๐Ÿ‘ 1
Thats only for public, our internal "apis" if you can call them that, are wild west and whatever the front end needs we just return it in the easiest format, normally arrays of objects.
a
I feel very much like the sheriff who has been assigned to the wild-west where the last sheriff "disappeared" at times with this code base ๐Ÿ™‚
d
Ha I feel you there. I have been in that position very often and have lost that batter a lot. If you can't get all the devs to agree on one small thing, it just won't happen.
Another thing I learned as sheriff, if the devs don't want it then you probably don't need it. Unless you have a direct non opinionated reason for wanting to make their lives both harder and then easier.
a
ha - I know what you mean. I'm thinking more of making it easier to onboard "devs of the future"
d
Hmmmm is that really where you have your sore spot in onboard, the return format of api calls?
a
No, but being consistent in the code we have is not a bad thing to aim for.
d
I mean true, but then your going again back to pushing an idea on existing devs for a reason that has little gain for a potential future dev.
The "WHY" are you making this change is what you need to determine how easy of an adoption you need that change to be to actually see it happen. If the "WHY" does't appear to be strong then you better make it as easy as writing serializeJson(c) in the code to be a replacement else adoption will be limited.
a
I'm not planning on enforcing it for existing endpoints that already work. Sure when we rebuild them in React (or whatever) then I'd like to be consistent in the server response. I'm actually picking up on a piece of work that someone else who has left started so it's not in production yet. I'm taking the opportunity to review it before it goes live and will then be stuck like that for the next 10 years.
d
I think I like the โ€˜ideaโ€™ of graphql to able to request just a small subset of data fields for a list of say organisations, e.g. organisation name and address from the same endpoint that could also give me all of the data for each organisation - which would be a much heavier data object. At the moment I have 2 options, provide a filter arg to show a fixed subset of data or the whole lot or create multiple endpoints for each permutation. But I fear there is less work in those options than building a graphql solution from scratch in cfml - maybe a node option will be something for the future, Iโ€™m not quite there in the node learning curve.
d
If you want to experiment with graphQL and what it can do the best strategy to start with is standing up and looking into apollo. It is something that can be put in front of a rest API as well as other servers, receive the graphQL request, parse it out to each appropriate server behind the scenes and then return a proper response. Obviously not as easy as a 2 sentence statement but it isn't to bad.
d
Apollo might just be the ticket - looks good!