Morzaram

Morzaram

Best Approach for Building a Sideapp in Elixir: Generating Images and PDFs

Hey everyone,

I’ve been tasked with creating a sideapp from our main Rails monolith at my company. I’m considering using Elixir for this project, but I’m unsure about the best approach to take. The sideapp’s main purpose is to generate images, PDFs, and other file formats. I’m seeking guidance on how to structure the entire cycle effectively and whether this approach would be considered a ‘microservice’.

My current plan is to utilize Exq to tap into the Sidekiq Redis server and process any tasks that come in through there. Albeit, not sure if that’s a good approach either. I’m uncertain about where to handle the database updates: on the Rails side or within the Elixir side. Let’s say someone wants to generate a PDF. I enqueue the process in Rails, Elixir picks it up, generates the file, and uploads it. But what should happen next? Should I create another job to pass the file back to Rails using Shrine for saving, or should I use and handle all the validation and persistence within Elixir?

We’re using shrine on the rails side with it’s specific format hence the hesitation to perform the persistence on the Elixir side.

Thank you in advance

Marked As Solved

evadne

evadne

Suggest to evaluate the following popular paradigms

  1. Shared DB task queue with Postgres

  2. Message queue (AWS SNS or custom message broker)

  3. Webhook request & response

  4. Synchronous HTTP/HTTPS request & response if performance is good

Do NOT touch the Redis instance used by Sidekiq, it is quite bad practice

Also Liked

Sebb

Sebb

There are many ways to create a PDF. For an invoice HTML to PDF is the easiest (you do not want or need docbook, latex, XSL-FO, …).

For HTML to PDF there are in general two ways to it:

  1. not using CSS3 paged media module. You just create a heex template for the invoice and run it through something like https://wkhtmltopdf.org or GitHub - bitcrowd/chromic_pdf: Convenient HTML to PDF/A rendering library for Elixir based on Chrome & Ghostscript · GitHub (this is easy but you can’t do some things like count pages, but could very well be enough for simple invoices)
  2. using CSS3 paged media module. This gives CSS the power to produce high quality content for print. The “lessons” section here https://print-css.rocks/lessons gives a good overview of the features, for example
  • the ability to count pages, know the amount of pages in a document
  • remove content from the body and put it in the page margins (running content, like current chapter for a book)
  • orphans/widows (do not have one single line of a para alone on a page)
  • break-control (no not break directly after a heading)
  • create TOC, create doc-entries with leaders (chaptername .......... page 7)
  • repeat table-headers when a table is continued on a new page (or add a subtotal at the page-break)

I would use (2) if you expect your invoices to have multiple pages* or if you plan to create more complex documents for print. Beware, that you may have to use a paid tool, see the tools section of print-css-rocks. But for an easy document like an invoice, some free tools should be able to do it. (browsers do not support CSS3 paged media)

*) maybe there are some tricks to get the page-count without CSS3-paged-media pages()-counter, so you could use (1) for that, but I’m not familiar with this tooling.

LostKobrakai

LostKobrakai

I’ve used https://weasyprint.org/ successfully in the past, and it’s free.

zimt28

zimt28

There’s also typst, a new typesetting system that is open source as well and looks very promising. You could use its cli or create a NIF using rustler.

Last Post!

Sebb

Sebb

sounds interesting, I’m also working on a PDF-publishing tool, maybe I’ll open source this if someone would be interested in contributing. Also using docraptor but heex instead of liquid.

Can you show your code? (I can’t yet, because it still has our production templates in it)

Where Next?

Popular in Questions Top

New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New

Other popular topics Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement