13 ms·
The original post could have been a bit more precise on this point. Basically, this math assumes something where the server-provided data changes in concert wit
by kellysutton 2y ago
The original post could have been a bit more precise on this point. Basically, this math assumes something where the server-provided data changes in concert with the frontend.
If we're using jsonapi, GraphQL, Thrift, or any other protocol that's not HTML, we need to do the following:
- Make the change on the server to support the new functionality. Deploy.
- Make the change on the client to adopt the new functionality. Deploy.
- Remove the old functionality from the server (optional)
Because the client is a separate application, it becomes riskier to deploy those changes together. I need to think about it more as a developer.
With server-authored HTML, this separate client + server deploy is not required.
- leptons 2y ago>With server-authored HTML, this separate client + server deploy is not required. SSR has been a thing in react for a long time.
- runako 2y agoIf the app has a backend, aren't we still talking about modifying two distinct apps (React + backend app) vs a single one? Obviously unless the team has committed to React SSR + React backend (is this common?)
- erikerikson 2y agoNot necessarily. We write Typescript for front and back ends, using statically rendered SolidJs, skipping SSR, and hosting the corresponding Typescript in Lambdas.
- runako 2y agoWould love to hear more about the deployment for that.
- erikerikson 2y agoCDK BucketDeployment to S3 fronted by CloudFront using a simple CloudFront function that redirects all paths to the index (main entry) file. `aws s3 sync` could have been fine. Was that the piece of deployment you were curious about? If not feel free to be more specific.
- runako 2y agoIt sounded like your app includes Lambdas as well? I assume there is another deployment pipeline for those? Thanks!
- erikerikson 2y agoYes, we use Lambdas but the CICD pipeline is shared and currently deploys everything everywhere every time though it will be more efficient to detect and only deploy deltas (there are some minor out-of-the-box detections of non-change but further optimization is very easily possible). For now, it's more important to pursue product market fit - the deploy is ~4 min per environment which is plenty good for current purposes and could easily be parallelized among other obvious and easy wins. OVERALL: I recommend the Serverless Framework but SSO wasn't supported at the time I started building so we use the CDK for deploying everything. The CDK stacks for the S3 bucket (etc.) and API are separate but that's a matter of factoring for clarity since it would be fine to have one big stack. For similar reasons, I factor the API and API deployment separately, alongside the WWW and WWW deployments. The entire company is a monorepo with a single command at the root that, beyond one-time account bootstrapping (which also uses CloudFormation and CDK), triggers scripts run locally or remotely to execute unit testing, deployment, and acceptance testing in a progressive multi-account deployment (on main). The CICD script installs dependencies, runs tests, identifies itself and uses that to assume account specific roles to deploy into the individual environments. This is all pretty excessive for a startup but seemed like a worthwhile and more secure foundation for actually trustworthy experimentation in delivering solutions into some of people's most sensitive private spaces and visions to go deeper. Meta-note: I accept that the separated pieces of the infrastructure have timing deltas and that some bugs could arise out of this once we've scaled. This is never not a problem but can have diminishing windows and/or effects with investment. This can be solved either by coding the API to handle current and current-1 contracts or maintaining concurrent current and current-1 lambda version deployments, where divergence occurs. None of that contradicts a single deployment of consistent code. There are deeper solutions with greater financial efficiency but I'll need a wild success scenario before those make business sense to invest in (monoimage k8s, knative, and so on). LAMBDA: we have built configuration that specifies the build entry points for tree shaking so that our deploy sizes are tiny and that is used by the CDK pipeline too. Our data tables are declared there too so that code and deploy share config. The Lambdas are grouped by event type (i.e. HTTP/ApiGateway, S3, Kinesis, EventBridge, etc.) and our declarations are structured according to generic Lambda defaults, a source-event-specific defaults, and a function specific declaration, allowing overrides at every level. This may sound complicated but it very cleanly organizes the configuration rather compactly, providing incredible clarity, and making scope of effect explicit and consistent. Everything is written in TypeScript which covers internal compile-time type safety but I have written a layer of middleware for the Lambdas so that they declare their contracts (that uses AJV to validate schema to type equivalence [JSON Schema is far more specific of course]) and entry points and enforces schema compliance (engineering requirements) at all boundaries in and out of the code base (i.e. receipt of API calls in client, receipt of client requests to API, S3 data, database puts/receipts, and so on). This got long so feel welcome to reach out (see profile) if you want more specific detail about any specific piece.
- silversmith 2y agoNot necessarily. Most of Rails+React apps I have worked on have had the frontend code live in the same repository, and get deployed during the same step. Yes, you have to keep API compatibility in mind when doing changes, because long-lived sessions might still exist. But has not been that much of a big deal in my experience.
- z33k 2y agoThe fashionable thing for a while now has been to write your react webapp as a single app. Here is one example of a "fullstack" react template: https://create.t3.gg/ https://create.t3.gg/
- runako 2y agoInteresting setup. Looks like getting to a zen state like this would have required them to migrate their backend from Rails to ts at some point. I can understand the engineering decision not to do that.
- bryanrasmussen 2y agoyeah and it sort of sucks in comparison to most other server-authored HTML solutions, in this statement I am of course thinking of Next but I suppose various forms of suckage will be found in other solutions.
- zelphirkalt 2y agoAnd to me both suck, compared to traditional template rendering like Jinja2 or Django Templates and those suck compared to SXML. React because of JSX and NextJS because of JSX and its assumptions about directory/file structure mapping to request routes, unless you change routing. JSX templates have that same feel, that PHP has from back in the day. Treating HTML as a string, implementing a wannabe HTML, that is not actually HTML, but slightly differen (for example the class attribute of HTML elements, or Fragment, <>) and enabling people to put JS logic inside the that string, mixing everything again, requiring to have a separate parser. Separate parser is basically what Jinja2 has or other templating engines like Django templates. React could have used any templating engine that already existed. But compare it to the elegance of SXML and treating HTML as the tree that is it, as structured data, enabling pattern matching on that, avoiding the need for a parser, and all other things that are in the language. Use. Structured. Data. It is so simple. Mainstream frameworks got a lot to learn still. They are still on the Kindergarden level of treating HTML as a mere string for most parts.
- Lutger 2y agoThere are a couple of reasons this is not convincing either: - Other factors can often dwarf the separate deployment overhead, especially given that the deployment steps are done so often it will force the team to make it efficient and get used to it. - There is no hard requirement for separate deployment in the first place, if we are just talking about react / spa you can deploy it in a single step. (Not saying you should) The point is: yes there is quite a lot of overhead. From separate deployments, from separate state management and I think the big ones are often having two different programming languages and having to align schema on frontend and backend. It is hard to deny this. But then saying that because of this overhead, these kinds of apps take 2x time to code implies denying there are benefits as well, that under given circumstances can outweigh the overhead. I think it is more interesting to assume that in some cases the benefits outweigh the cost of the overhead, and in others they do not.