Anyone using a Phoenix LiveView Client to access a Phoenix Absinthe API?

Hi,

I have built a backend API using Phoenix and Absinthe (The intention is to have a Web Client and a couple of different Mobile Apps using the API).

For the Web Client I have been playing around with Phoenix (and LiveView) and have it all working for basic calls. However, during my research it seems that using something like Apollo has the benefit of client side data management (Particularly caching).

Has anyone used a Phoenix Client to access a Phoenix Absinthe API? Any tips will be great.

Andrew

3 Likes

Why would you want to access GraphQL API of your own application from within LiveView in the same application? That makes little to no sense.

Hey @andrewb, we’ve been doing this for the past 6 months or so. We’ve built an entire suite of UI applications that get data exclusively from our GraphQL API and it’s been a really excellent experience. I’ve just gotten back from a long bit of traveling so I’m going to just post some jumbled thoughts on the matter now, and then hopefully follow up later with more discussion.

To address @hauleth’s point first, we at least did not do these as the same application. We have a rather large pre-existing Logistics IoT platform from which we had been driving React UIs via GraphQL. For various reasons we wanted to look at using LiveView instead of React for a new suite of user experiences. We considered building these into the original application, but several things made that a non optimal plan:

  • The core platform is very large. Splitting up the apps makes the review process simpler because you can be absolutely certain that UI changes are only touching UI code. We can deploy that without concern for anything that’s happening in the underlying platform.
  • The core platform is very critical. We didn’t want to risk stuff like a badly written live view eating up tons of memory and cause OOM crashing the platform containers. We run replicas of course but separating the deployed artifacts in general allowed us to have distinct operational flows for each.

With that said, here are some assorted things we learned:

  • Pro: querying GraphQL is really easy to grok. We had our React devs building LiveView UIs in no time flat because they could just look at the API docs as to what was available, query it, throw it in the UI. Even if you’re doing everything through “Phoenix Contexts” with nice clear boundaries and no out of band ecto querying, those context functions all have ad hoc Elixir specific ways of specifying what additional data you want to load. Discoverability is low, and any docs written are pure text, they aren’t generated from what’s actually possible.

  • Pro: GraphQL subscriptions works very well with LiveView. Query stuff on mount, open a socket, subscribe to the same stuff, and when you get a message replace the state. Boom, everything is immediately live, it’s like magic.

  • Pro/Con: If your API doesn’t support something yet, you need to add an API for it. This is sort of a Con, but in my view it works out to be a pro. Any other clients you have (mobile, customers, etc) benefit from the additions, and you get a self documented API out of the deal.

  • Con: Query results are decoded JSON strings. If you want nice atom keyed stuff you have to do some extra work. We started by just having a bunch of ecto embedded schemas in the app that we cast the GraphQL results into so we’d get nice atom keys and scalar type casting. This obviously sucks though so I’ve been working on some Absinthe.Client functionality that introspects a schema and can then cast results from that schema into nice Elixir “native” feeling data structures.

  • Con: You need to do a little bit of your own work to create an Absinthe client. I will try to open source the wrapper I wrote about the Phoenix Channel client here shortly cause that’s the most complicated bit. Pure HTTP request based queries are simple enough, pick your favorite HTTP client library and go for it. Arguably though if you’re doing subscriptions you want everything over the socket so I need to make sure there are nice APIs for that sort of thing.

All in all, I’d do it again, it’s been a wonderful experience. It helped that we already had a decent sized GraphQL api already so in particular the first like 70% of what we did UI wise didn’t require much or any changes to the API itself. Even as we’ve continued to develop this though, that API boundary has provided the perfect demarcation line for work across teams.

For small personal projects I’m not sure if it’d be worth it. I’m in the midst of setting up a nerves based backyard garden watering system and for that I will probably just wire live view directly to the underlying code. For anything at a company, I’d definitely recommend considering it.

30 Likes

Ooo, this sounds rather interesting!

Thanks for the detailed answer Ben, it is greatly appreciated. I look forward to seeing the wrapper.

Thanks again.

any updates on this?

Hi @benwilson512, I’m considering using the Absinthe GQL + LiveView approach on a new project, feel like it’s a natural architecture which enforces clear boundaries. Would love to see the Absinthe client functionality you describe above, thanks for all your work on Absinthe!

2 Likes

I will not be another person to ask you to share the code you wrote, but I would like to ask your opinion please.

For a small but experienced company about to build a realtime app with Phoenix backend, which would you recommend today:

  1. LiveView frontend with LiveView sockets
  2. LiveView frontend with Absinthe GraphQL API
  3. Relay (react frontend) with Absinthe API

Option 1 seems safe and easiest to prototype. The frontend might be harder to “polish”.
Option 2 seems trickiest to implement. As you say, Absinthe API will return JSON format, no atoms. Moreover, to repeat, I find the Phoenix frontends take more work to “polish”.
Option 3 seems safe and possibly most rewarding (in terms of effort-to-result). I am strongly leaning toward this approach.

I would very much appreciate any thoughts you have on this. It’s OK if they are just subjective opinions or if you ramble a bit, I am genuinely curious what path you would choose today if building a new application (let’s say the use case is a fast-food chain app, as described in “Crafting GraphQL APIs in Elixir with Absinthe”). Maybe there is a secret 4th path that is the path of ultimate power? Please, reveal your secrets, senpai.

1 Like

Would love to see a basic example app that showcases how to use LiveView and Absinthe together to produce GraphQL APIs with realtime support. We currently use GraphQL in production but there is quite a bit of boilerplate we deal with for realtime subscriptions.

4 Likes

@venkatd I would be also interested in seeing an example application of using Absinthe and LiveView. Maybe, @bruce and @benwilson512 can add a chapter or 2 that covers this topic in “Craft GraphQL APIs in Elixir with Absinthe 2nd edition”. :thinking:

1 Like

Any news @benwilson512 on that client you spoke about earlier :slight_smile: ?

Id love to write a graphql server with phoenix and absinthe and then in another elixir based service consume the graphql api. As things stand id have to use another language to consume the api (like javacript).

1 Like

Any updates on this? Such an interesting combo!