-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.html
More file actions
703 lines (598 loc) · 39.3 KB
/
Copy pathindex.html
File metadata and controls
703 lines (598 loc) · 39.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Frontend First Development</title>
<link rel="apple-touch-icon" sizes="57x57" href="apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png">
<link rel="manifest" href="manifest.json">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="main.css">
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="dialine1"></div>
<div class="dialine2"></div>
<div class="logo">FFD</div>
<ul class="menu">
<li>
<a href="#about">About</a>
</li>
<li>
<a href="#why">Why</a>
</li>
<li>
<a href="#technologies">Key technologies</a>
</li>
<li>
<a href="#workflow">Workflow</a>
</li>
<li>
<a href="#status">Status</a>
</li>
<li>
<a href="#community">Community</a>
</li>
</ul>
<h1>Frontend First Development</h1>
<div class="container">
<div class="title">
<span>Frontend</span>
<br />
<span>First</span>
<br />
<span>Development
<span>
</div>
</div>
<article>
<h2>TL;DR</h2>
<p>Solve friction between backend and frontend with an API mocking server, GraphQL, automatic server side rendering
and a schema first headless CMS of your choice.</p>
<h2 id="about">About</h2>
<p>Back in the day, web development was a lot less complex. Those days the backend basically was the frontend, today
the backend and frontend are two distinct and often rather complex entities.
<mark>Syncing frontend templates and assets with backend rendered markup is often anything else than straight forward.</mark>
Depending on the CMS driving your site, you get more or less container markup wrapping the data outputted by
different modules and either you overwrite a lot of server templates (if that is even possible!) or you adapt
your CSS (not always possible either with flex based layouts) to integrate your markup.</p>
<p>
<mark>But thankfully there’s finally a promising path out of this mess!</mark> By doing as much as possible on the
frontend, ideally component based so you can abstract complexity into smaller more focused pieces, and than render
the routes and markup with a server side rendering framework, you never again have to sync markup from different
sources. And by additionally mocking the API server, we can flexibly and much faster tinker with the project
till everything is perfect, without first implementing the feature on the backend, making us more responsive
and our clients happy.</p>
<p>Let’s be honest, letting the backend render markup was never a great idea anyway. Not only does it create the described
friction between frontend and backend, it also isn’t really the expertise of backend developers, especially when
it comes to things like accessibility and above the fold performance optimisations.
<mark>A frontend first development workflow can solve us all these problems</mark> and this place here will try to
do it’s best to point you in the right directions.</p>
<blockquote>A content management system is for managing content, not for content rendering!</blockquote>
<h2 id="why">Why</h2>
<p>Let’s first have an overview why we actually need to move to a frontend first development workflow by comparing its
advantages and possible disadvantages.</p>
<h3>Advantages:</h3>
<ul>
<li>
<mark>Less friction between FE & BE:</mark> Because a headless CMS only manages contend and delivers it to the
frontend over ideally a GraphQL API, you never need to sync markup between frontend & backend and as GraphQL
APIs are auto documenting, you always know exactly what’s available to you as a frontend developer.
</li>
<li>
<mark>Enables tinkering:</mark> As you are mocking the API, changes can be implemented much faster than actually
building the backend service first. So fast actually, that you can do live tinkering together with the client,
right on the product.
</li>
<li>
<mark>Easier debugging:</mark> Moving most of the business logic to the frontend and having a strongly typed auto
documenting API makes it very clear where an error comes from. In 99% of all cases it will originate from
your frontend code and you can debug it at one single place. Strongly typed languages like TypeScript or
Reason ML or even Elm can tell you where bugs are even while you code.
</li>
<li>
<mark>Client friendly:</mark> Clients often don’t have the expertise to judge an abstract technical concept without
something they can interact with. By developing frontend first, clients can judge a feature as realistically
as possible before any backend is implemented, making sure that stakeholders involved make informed decisions.
</li>
<li>
<mark>More focused backends</mark> Frontend first enables the backend to focus and optimise the right thing. By
knowing exactly what the frontend queries are, for example with the help of Apollo Engine, they can add caching
layers exactly where needed and use the freed up time to optimise the content management forms, delivering
the best experience to clients.
</li>
<li>
<mark>Skill targeting</mark> Frontend developers are the experts on writing HTML5, accessibility, optimising above
the fold performance ... why should the backend developers ever render markup for them?
</li>
<li>
<mark>Focus on the right thing:</mark> With frontend first, you spend most of the development time where it counts,
the thing people see and interact with, and automate as much of the rest as possible.
</li>
<li>
<mark>Decouple backend implementation:</mark> As you are developing data structures frontend first, the backend is forced to develop the API service decoupled from the actual implementation details like the database table names, field names in that table or the attribute names of an external API. This is very good practice as it protects the API from changing after an implementation change, but is often not done because of the extra overhead in development.
</li>
</ul>
<h3>Possible disadvantages:</h3>
<ul>
<li>
<mark>Frontend developer maturity:</mark> Designing normalised data structures is traditionally a backend job,
so frontend developers need to acquire this skill first so they can perfectly mock API services. But looking
at what the frontend community achieved in recent years, I’m not at all worried that this will be a big issue.
It is no surprise that the frontend community made the Flux paradigm popular again in favour of MVC, solving
many issues of the past.
</li>
<li>
<mark>Works better with a serial workflow:</mark> Ideally, the backend starts to build the real GraphQL API right
after the frontend has implemented all features. While there are often external API integration tasks the
backend can focus in the meantime, it definitely can happen that the backend is blocked by the frontend,
waiting for an implementation. But to be honest, up till now, the frontend was often blocked by the backend
for the same reasons, so this is not exactly a new issue after all.
</li>
</ul>
<h2>Less friction between FE and BE</h2>
<p>Let’s have a closer look at one of the pros, one that creates a lot of issues with current workflows, to get a better
idea why frontend first is such a tempting idea.</p>
<h3>Usual developer workflow:</h3>
<p>
<img src="two-path-workflow.svg">
</p>
<p>
<mark>This workflow creates friction when both paths meet!</mark>
</p>
<h3>Frontend First Workflow:</h3>
<p>
<img src="frontend-first-workflow.svg">
</p>
<p>
<mark>Only one development path, no friction!</mark>
</p>
<p>Information architecture and technical specification is mostly a first draft. Than changes happen after the client
can interact with the frontend or living style guide, while iterating till every stakeholder is happy. Without
a frontend first approach, this leads to friction everywhere. Even content creation is more and more frontend
first focused these days, just think of headlines that have to be limited to certain lengths to match the design
and use fitting word lengths to break nicely in the limited space designed for that element.</p>
<h2 id="technologies">Key technologies</h2>
<p>Thanks to some key technologies of recent years like GraphQL and all the tooling around it, we are now pretty close
to make a truly frontend first workflow possible!</p>
<h3>API server mocking</h3>
<p>The first key technology is API server mocking. On a frontend first workflow, you want to start working before any
backend is set up. Traditionally we used hardcoded data and mocked JSON endpoints to mock our API endpoints,
but
<mark>these days it’s now possible to mock a whole REST or GraphQL server with just some sample data</mark>. These
kind of servers support all the CRUD operations (create, read, update and delete) and especially with GraphQL,
can feel like the real thing, but with almost no effort. This is very important, as you can create prototypes
that are
<mark>so close to the real thing, that your client can get a very realistic impression of the final product, without
ever having to first setup a backend CMS.</mark> The other important feature of this approach, is that you
can design your sample data so realistically, that you can test frontend edge cases, for example different content
lengths, right from the beginning. As you’re working with sample data, changes to your API are done in seconds,
even changing normally complicated stuff like relationships, becomes really easy.</p>
<blockquote>If you want to have super fast iterations on your API, there’s no way around an API mocking server.</blockquote>
<p>Let’s have a look at an example. The following sample data defines a blogging API where users have posts and posts
can have comments and comments can be replies to other comments.</p>
<script src="https://gist.github.com/FrediBach/ac09a0dc589d5c20570b2c64aa336d59.js"></script>
<p></p>
<p>Of course in a real world app, you would add more realistic content (no lorem ipsum!) and more entries for each type
to make it more realistic.</p>
<p>However,
<mark>this small sample data file already defines quite a few features that would normally take quite a while to implement.</mark>
For example there are multiple relationships between types, like that each user can have posts and comments assigned
to him. Each post can have multiple comments and comments can reference another comment (replies). Some fields
are optional, for example “comment_id” on the comment type as a post can have no comments.</p>
<p>Further, if we have to add a new field to our schema, all we need to do is add that field to the sample data, for
example an email field on the user type:</p>
<script src="https://gist.github.com/FrediBach/258fdbcbadb696d0a917cf81adb459e9.js"></script>
<p></p>
<p>Just restart the mocking server, and that’s it! Same thing for relationships, just add it to your sample data, restart
the mocking server and you’re done. It couldn’t be easier and faster (well, beside adding a watcher to the mocking
server so you don’t have to restart it after every single change), making it possible to
<mark>dynamically alter your backend without actually writing any backend code, making it possible to iterate fast
and even tinker live on the source together with your client!</mark>
</p>
<h4>API mocking server tools:</h4>
<ul>
<li>GraphQL:
<ul>
<li>
<b>NEW: Hasura JSON Data Import</b> (using sample data)
<span class='arrow'>
<svg width="11px" height="10px" viewBox="0 0 11 10" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="right-arrow">
<path d="M1.77635684e-14,5 L9,5" id="rod" stroke="#000000" stroke-width="2"></path>
<path d="M11,5 L6,0.5 L6,9.5 L11,5 Z" id="point" fill="#000000"></path>
</g>
</svg>
</span>
<a href="https://github.com/hasura/json-data-import">https://github.com/hasura/json-data-import</a>
</li>
<li>
<b>JSON GraphQL Server</b> (using sample data)
<span class='arrow'>
<svg width="11px" height="10px" viewBox="0 0 11 10" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="right-arrow">
<path d="M1.77635684e-14,5 L9,5" id="rod" stroke="#000000" stroke-width="2"></path>
<path d="M11,5 L6,0.5 L6,9.5 L11,5 Z" id="point" fill="#000000"></path>
</g>
</svg>
</span>
<a href="https://github.com/marmelab/json-graphql-server">https://github.com/marmelab/json-graphql-server</a>
</li>
<li>
<b>EasyGraphQL Mock</b> (schema first mocking)
<span class='arrow'>
<svg width="11px" height="10px" viewBox="0 0 11 10" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="right-arrow">
<path d="M1.77635684e-14,5 L9,5" id="rod" stroke="#000000" stroke-width="2"></path>
<path d="M11,5 L6,0.5 L6,9.5 L11,5 Z" id="point" fill="#000000"></path>
</g>
</svg>
</span>
<a href="https://github.com/EasyGraphQL/easygraphql-mock">https://github.com/EasyGraphQL/easygraphql-mock</a>
</li>
<li>
<b>GarphQL Faker</b> (faking data based on directives)
<span class='arrow'>
<svg width="11px" height="10px" viewBox="0 0 11 10" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="right-arrow">
<path d="M1.77635684e-14,5 L9,5" id="rod" stroke="#000000" stroke-width="2"></path>
<path d="M11,5 L6,0.5 L6,9.5 L11,5 Z" id="point" fill="#000000"></path>
</g>
</svg>
</span>
<a href="https://github.com/APIs-guru/graphql-faker">GitHub - APIs-guru/graphql-faker: 🎲 Mock or extend your GraphQL API with faked data. No coding required.</a>
</li>
</ul>
</li>
<li>REST:
<ul>
<li>
<b>JSON Server</b>
<span class='arrow'>
<svg width="11px" height="10px" viewBox="0 0 11 10" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="right-arrow">
<path d="M1.77635684e-14,5 L9,5" id="rod" stroke="#000000" stroke-width="2"></path>
<path d="M11,5 L6,0.5 L6,9.5 L11,5 Z" id="point" fill="#000000"></path>
</g>
</svg>
</span>
<a href="https://github.com/typicode/json-server">GitHub - typicode/json-server: Get a full fake REST API with zero coding in less than 30 seconds
(seriously)</a>
</li>
</ul>
</li>
<li>General:
<ul>
<li>
<b>Blowson</b>
<span class='arrow'>
<svg width="11px" height="10px" viewBox="0 0 11 10" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="right-arrow">
<path d="M1.77635684e-14,5 L9,5" id="rod" stroke="#000000" stroke-width="2"></path>
<path d="M11,5 L6,0.5 L6,9.5 L11,5 Z" id="point" fill="#000000"></path>
</g>
</svg>
</span>
<a href="https://github.com/FrediBach/Blowson">GitHub - FrediBach/Blowson: Blow up JSON like sample data in an awesomely realistic way!</a>
</li>
</ul>
</li>
</ul>
<p>Our recommendation is of course to use one of the GraphQL variants, as it has multiple advantages like having just one very
flexible endpoint, no over and under fetching and auto documentation and autocomplete for all possible queries
and fields. And with Hasura, you even get a full GraphQL Engine from your sample data, how cool is that?!</p>
<blockquote>GraphQL is the enabler of a true frontend first workflow!</blockquote>
<h3>GraphQL</h3>
<p>In a real world application, where performance counts, REST runs into problems pretty fast. What normally happens
on every project, is that you start implementing custom endpoints for pretty much everything, to prevent over
and under fetching and especially having to call multiple endpoints to get all the data you need. Thankfully
GraphQL solves all these problems.
<mark>Not having to write custom endpoints, makes the switch from a mocked API to the real thing extremely easy.</mark>
In most cases all you need to change is the url to the real API. Here is an example query for the sample data
posted above:</p>
<script src="https://gist.github.com/FrediBach/a6eacfd57889a0a5bda7374ef542c90e.js"></script>
<p></p>
<p>With a REST API, this simple query could already end up in a maximum of 11 requests to the server as you would have
to do one extra request for each unique user, definitely not something you want to happen on a mobile connection!
That’s why in any realistic real world REST setup, you would create a custom endpoint for this case, but with
GraphQL that isn’t needed at all, allowing us to easily mock the API in a realistic way.</p>
<p>For consuming a GraphQL endpoint, I highly recommend Apollo. It hits a sweet spot between advanced features like
caching, optimistic UI, refetching etc. and ease of use and it’s where the community is at right now, so you
have nice documentation, tons of articles and a great community in case you run into problems. For very simple
APIs and frontends, Lokka can be a great alternative.</p>
<ul>
<li>
<b>Apollo:</b>
<a href="https://www.apollographql.com/">Apollo GraphQL | Learn about the Apollo platform: Client, Engine, GraphQL servers, GraphQL support, and more.</a>
</li>
<li>
<b>Lokka:</b>
<a href="https://github.com/kadirahq/lokka">https://github.com/kadirahq/lokka</a>
</li>
</ul>
<p>I would personally stick with Apollo, as it integrates nicely with server side rendering frameworks, as we’ll see
next and has it’s own caching proxy solution that you can use out of the box.</p>
<p>Now what if I need to integrate existing REST API endpoints? Maybe even external third party ones that I can’t port to GraphQL? With Apollo this is actually not a big issue.
Thanks to Apollo Link Rest, you can easily use REST APIs together with GraphQL, in the same queries.</p>
<p>In case you don’t expect to use a CMS to manage the data, you can relatively easily setup a real GraphQL server.
Have a look at GraphQL engines, that make it possible to setup real database driven endpoints without too much
effort:</p>
<ul>
<li>
<b>Prisma:</b>
<a href="https://www.prisma.io/">Prisma | Open-Source GraphQL ORM for GraphQL Servers</a>
</li>
<li>
<b>Hasura:</b>
<a href="https://hasura.io/">GraphQL on Postgres | Hasura</a>
</li>
<li>
<b>PostGraphile</b>:
<a href="https://www.graphile.org/postgraphile/">Graphile | Powerful, Extensible and Performant GraphQL APIs Rapidly</a>
</li>
<li>
<b>GrandStack:</b>
<a href="https://grandstack.io/">GRANDstack · Build full stack graph applications with ease.</a>
</li>
<li>
<b>GraphQL Genie:</b>
<a href="https://github.com/genie-team/graphql-genie">GraphQL Genie: Turn your GraphQL Schema into a fully featured GraphQL API with referential integrity, inverse updates and subscriptions</a>
</li>
</ul>
<p>Those are great options if you’re building all functionality by yourself (or your team), without a CMS managing your
data, but I wouldn’t do it initially, as it makes tinkering with your data quite a bit more involved.</p>
<h3>Headless CMS</h3>
<p>If you need a strong admin interface for content management, with approval workflows, the flexibility to integrate
other services and other enterprise requirements, you normally don’t build everything yourself from scratch,
you choose an enterprise level CMS that can handle all of that stuff already.
<mark>Sadly all the currently most popular CMS solutions on the market aren’t very well suited for a frontend first
workflow.</mark> But thankfully, new contenders are entering the market and are now realising the potential
of a schema based GraphQL API approach. Directus for example is almost database agnostic, so you could
write your own connector to, for example Hasura, our current GraphQL engine favorite, and manage the content
decoupled from the database/API server. This would even solve the issue that Directus doesn't have a GraphQL API, as
you would use the API from the Hasura Engine. It's not perfect, but we're not that far away from an optimal solution, either.</p>
<p>Here’s an incomplete list of possible options:</p>
<ul>
<li>
<b>Contentful</b>:
<a href="https://www.contentful.com/">Contentful: Content Infrastructure for Digital Teams</a>
</li>
<li>
<b>Directus</b>:
<a href="https://getdirectus.com/">Directus - Open-Source Headless CMS</a>
</li>
<li>
<b>GraphCMS</b>:
<a href="https://graphcms.com/">GraphCMS - The GraphQL Headless CMS</a>
</li>
<li>
<b>Mozaik</b>:
<a href="https://www.mozaik.io/">Mozaik | Next generation headless GraphQL CMS</a>
</li>
<li>
<b>GENTICS Mesh</b>:
<a href="https://getmesh.io/">Gentics Mesh - The open source headless CMS for developers</a>
</li>
<li>
<b>Canner (with support for Prisma!):</b>
<a href="https://www.canner.io/">Canner - Make CMS simple</a>
</li>
<li>
<b>Relax CMS:</b>
<a href="https://github.com/relax/relax">GitHub - relax/relax: New generation CMS on top of React, Redux and GraphQL</a>
</li>
<li>
<b>Dato CMS:</b>
<a href="https://www.datocms.com/docs/content-delivery-api/querying/">Querying the API - Content Delivery API - DatoCMS</a>
</li>
<li>
<b>Headless WordPress:</b>
<a href="https://github.com/postlight/headless-wp-starter">Headless WordPress + React Starter kit</a>
</li>
</ul>
<h3>Server Side Rendering</h3>
<p>When going frontend first, your CMS or API backend should only deliver the content and not render the frontend routes
and markup.
<mark>Now you could build everything as a single page app (SPA), but that has some serious disadvantages when it comes
to search engine optimisation (SEO)</mark>, a must for client projects. Thankfully we have great options
now that can solve this issue. The idea is that you build your frontend as you would in a SPA, but than have
a SSR framework that can extract the routes from your SPA and render them server side. Two options:</p>
<ul>
<li>
<b>Rouge:</b>
<a href="https://github.com/alidcastano/rogue.js">GitHub - alidcastano/rogue.js: Rogue.js - a nearly invisible framework for creating server-rendered React
applications</a>
</li>
<li>
<b>Reframe</b>:
<a href="https://github.com/reframejs/reframe">GitHub - reframejs/reframe: Framework to create web apps.</a>
</li>
<li>
<b>Next.JS:</b>
<a href="https://nextjs.org/">Next.js</a>
</li>
<li>
<b>After.js:</b>
<a href="https://github.com/jaredpalmer/after.js">GitHub - jaredpalmer/after.js: Next.js-like framework for server-rendered React apps built with React Router
4</a>
</li>
<li>
<b>Serlina:</b>
<a href="https://serlina.js.org/#/">Serlina - A progressive React serverside-rendering framework.</a>
</li>
<li>
<b>Razzle:</b>
<a href="https://github.com/jaredpalmer/razzle">GitHub - jaredpalmer/razzle: ✨ Create server-rendered universal JavaScript applications with no configuration</a>
</li>
<li>
<b>ReactQL:</b>
<a href="https://reactql.org/">ReactQL: Modern stack for React+GraphQL</a>
</li>
<li>
<b>Nuxt (Vue based):</b>
<a href="https://nuxtjs.org/">Nuxt.js - Universal Vue.js Applications</a>
</li>
</ul>
<p>The nice thing with Rogue is that it guesses your endpoints based on your React Router 4 setup. This way you can
build your project like a normal single page app, and
<mark>Rogue will build the server side rendering part automatically based on your apps routes</mark>, meaning you don’t
have to define anything twice and changes to your routes are immediately reflected to your server side routes.</p>
<blockquote>Server side rendering can be quite easy these days, you don’t have to come up with your own solutions.</blockquote>
<p>The other ones are less automatic, but can be great options, as well. Next.JS for example is quite battle tested
by now, so you probably won’t run into early adopter issues.</p>
<h2 id="workflow">The Frontend First Development workflow</h2>
<p>As we had a look at the needed technologies now, let’s have a closer look at the frontend first workflow itself:</p>
<h3>1. Create realistic sample data for your project</h3>
<p>This is where everything starts. Initially build a simple sample data file that contains all the types, relationships
and has at least one entry per type that only contains the required fields, so that the mocking server can guess
the schema correctly. As the project goes on, start to add additional more realistic data. Work as long as possible
with sample data, so you can implement changes as fast as possible.</p>
<h3>2. Run the API mocking server</h3>
<p>You can now run the mocking server using your sample data locally using either GraphQL JSON Server or less recommended,
JSON Server for a REST API.</p>
<h3>3. Build your server side rendered app</h3>
<p>Setup your frontend with one of the server side rendering frameworks that can automate the server rendering part,
currently either Rogue or Reframe. Both frameworks make it possible to render your routes server side in a SEO
friendly way, without having to setup that part yourself, making it possible for you to focus on building your
frontend.</p>
<p>
<mark>For bigger projects, it is recommended to build your frontend on top of a living style guide, design system and
component library.</mark> Here are some libraries that can help you with that:</p>
<ul>
<li>
<b>Catalog:</b>
<a href="https://www.catalog.style/">Catalog</a>
</li>
<li>
<b>Storybook:</b>
<a href="https://storybook.js.org/">https://storybook.js.org/</a>
</li>
<li>
<b>React Styleguideist:</b>
<a href="https://react-styleguidist.js.org/">React Styleguidist: isolated React component development environment with a living style guide</a>
</li>
<li>
<b>Styled System:</b>:
<a href="https://jxnblk.com/styled-system/">Styled System</a>
</li>
</ul>
<h3>4. Iterate with the client till the frontend is perfect</h3>
<p>With the new powers and flexibility you get using a frontend first development workflow, use this chance to iterate
often and improve the product together with your client. An agile project setup is a must in a project like this.
While the one path workflow at first looks a lot like waterfall, your project actually profits most from an agile
workflow, where you iterate fast and often.</p>
<h3>5. Generate the schema for the backend and let them build the real API server</h3>
<p>Using your final sample data, you can now easily generate the GraphQL schema for the backend. From the same guy that
made JSON GraphQL Server, you can use this library to automatically generate the schema:
<a href="https://github.com/marmelab/graphql-schema-from-json">GitHub - marmelab/graphql-schema-from-json: Guess a GraphQL schema from json data</a>
</p>
<h3>6. The backend generates (automatically or not) the admin interface based on the schema</h3>
<p>This is the point where you start implementing the CMS or the admin forms for the API server. Sadly on most current
CMS options, this isn’t an automatic process where you just import the schema and you’re done. This step still
involves clicking your backend types together, but things are starting to change, making this a one click process
like it should. If you’re running you project on a GraphQL engine, things are a little bit easier, but your entry
forms won’t be as client friendly as with a CMS solution.</p>
<h3>7. Connect the SPA to the real backend</h3>
<p>As soon as the backend is ready, switch your GraphQL endpoint in your SSR rendered app to the real thing. Deploy
and you’re done.</p>
<p>… and lastly …</p>
<h2 id="status">Are we there yet?</h2>
<p>Almost.</p>
<p>There are still a few things that need to be improved before this approach can really take off. For example the GraphQL
API mocking server still has some missing features (Edit: With Hasura JSON Data Import, we made a big step forward!):</p>
<ul>
<li><del>Realistic error handling</del>
</li>
<li><del>Query performance simulation by adding delays based on the complexity and depth of a query</del>
</li>
<li><del>Sort, filter and pagination on sub queries</del>
</li>
<li><del>Automatic id’s and support for non integer id’s</del>
</li>
<li>Simulation of a auth permission system
</li>
</ul>
<p>On the server rendering side of things, many tools are still quite new and not extremely battle tested.</p>
<p>
<mark>But overall it’s a good time to start building frontend first and help the community improve the available tools
as much as you can.</mark>
</p>
<p>Looking at the available CMS solutions, it would be nice if you could import your sample data directly, or at least
the generated schema and than use the database from your GraphQL engine, for a real schema first experience.</p>
<p>Talking about schema first development. You may wonder why a sample data first and not schema first approach is described
here. Using schema directives to tell the server how to generate sample data could look like this:</p>
<script src="https://gist.github.com/FrediBach/297cb906f88c70f120c48bee8f497390.js"></script>
<p></p>
<p>Or how GraphQL Faker does it:
<a href="https://github.com/APIs-guru/graphql-faker">GitHub - APIs-guru/graphql-faker: 🎲 Mock or extend your GraphQL API with faked data. No coding required.</a>
</p>
<p>Personally I believe that you get much better results with realistically mocked data than with fake computer generated
fields. I do think GraphQL Faker has it’s uses, maybe even by combining it with a sample data server, but
<mark>working with clients and design driven development, realistic data is a must have.</mark>
</p>
<h2 id="community">Frontend First Community</h2>
<p>If you like that idea of frontend first development, please join our new community on Reddit: <a href="https://www.reddit.com/r/FrontendFirst/">r/FrontendFirst</a></p>
<p>And join the newsletter where we monthly post all the latest tools and articles about this topic.</p>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/horizontal-slim-10_7.css" rel="stylesheet" type="text/css">
<style type="text/css">
#mc_embed_signup {
background: rgba(255,255,255,0.8);
border-radius: 3px;
clear: left;
font: 14px Helvetica, Arial, sans-serif;
width: 100%;
padding: 20px;
}
/* Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<div id="mc_embed_signup">
<form action="https://frontendfirstdevelopment.us18.list-manage.com/subscribe/post?u=8dab907200cb52013a1aaf830&id=00d38f2abb"
method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>
<div id="mc_embed_signup_scroll">
<label for="mce-EMAIL">Subscribe to our mailing list</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required>
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true">
<input type="text" name="b_8dab907200cb52013a1aaf830_00d38f2abb" tabindex="-1" value="">
</div>
<div class="clear">
<input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button">
</div>
</div>
</form>
</div>
<!--End mc_embed_signup-->
<p>Most importantly, help the community improve the tools, either by using them and post bug issues or feature request
or by directly getting involved in the development of these tools! :-)</p>
</article>
<footer>
(c) 2018 by Fredi Bach
<br />
<a href="https://www.unic.com/">Unic AG</a>
</footer>
<script src="main.js"></script>
</body>
</html>