What about going Jamstack? #9908

Closed
opened 2025-11-02 08:52:49 -06:00 by GiteaMirror · 9 comments
Owner

Originally created by @pboguslawski on GitHub (Nov 29, 2022).

Feature Description

https://github.com/go-gitea/gitea/pull/16052 shows us two separate set of handlers for maintenance: one for web UI and one for "API clients". Two different sets of authentications for both (i.e. auth cookies and CSRF in web UI only). Current way (splitting routes, fixing on token auth for API) sounds not very flexible for future.

Idea to consider for Gitea's future: treating web UI as any other API client (and wiriting it as static SPA, Jamstack way) and making go backend API server only, one for all Gitea's clients (web ui, mobile, etc.). Maybe it's possible to smooth migrate using new API v2 and switch web UI elements to it when ready and supporting API v1 till the and of API v2 implementation?

I can see Github UI works like SPA today so probably Gitea can go SPA way too; single API maintenance, frontend UI separation from backend (easier replacing with new techologies like svelte/wasm/... in the future if required) is worth cosideration IHMO.

Seems CSRF protection may be based on Origin header only today (supporting only up to date, compatible web browsers) and throw away CSRF tokens?

Screenshots

No response

Originally created by @pboguslawski on GitHub (Nov 29, 2022). ### Feature Description https://github.com/go-gitea/gitea/pull/16052 shows us two separate set of handlers for maintenance: one for web UI and one for "API clients". Two different sets of authentications for both (i.e. auth cookies and CSRF in web UI only). Current way (splitting routes, fixing on token auth for API) sounds not very flexible for future. Idea to consider for Gitea's future: treating web UI as any other API client (and wiriting it as static SPA, Jamstack way) and making go backend API server only, one for all Gitea's clients (web ui, mobile, etc.). Maybe it's possible to smooth migrate using new API v2 and switch web UI elements to it when ready and supporting API v1 till the and of API v2 implementation? I can see Github UI works like SPA today so probably Gitea can go SPA way too; single API maintenance, frontend UI separation from backend (easier replacing with new techologies like svelte/wasm/... in the future if required) is worth cosideration IHMO. Seems CSRF protection may be based on Origin header only today (supporting only up to date, compatible web browsers) and throw away CSRF tokens? - https://www.mixmax.com/engineering/modern-csrf - https://github.com/sveltejs/kit/issues/72 - https://github.com/sveltejs/kit/pull/6510/files ### Screenshots _No response_
GiteaMirror added the type/proposal label 2025-11-02 08:52:49 -06:00
Author
Owner

@delvh commented on GitHub (Nov 29, 2022):

I agree to some extent:
Yes, I also think it is a good idea to use the UI as API where possible, however, there would be a lot of work to implement this completely:
Our UI routes are constantly updated, and are not backward compatible. With this approach, they would need to be.
Then, our UI is currently rendered mostly through Go templates. Changing all that is a lot of work, as that will basically amount to rewriting the entire frontend.
Furthermore, by moving away from Go templates we would lose the amount of customizability that is currently possible.
I did not even touch the topic of JS being disabled, or requests going missing yet: With your proposed approach, those concerns must also be answered, even though developers like to assume they are not there.
Lastly, there is a lot of UI-specific code explicitly tailored for the UI inside the backend. That would again be really hard to change.

cloc currently produces the following:

    4391 text files.
    2907 unique files.                                          
    1502 files ignored.

1 error:
Line count, exceeded timeout:  routers/web/web.go

github.com/AlDanial/cloc v 1.94  T=5.15 s (564.9 files/s, 125627.9 lines/s)
--------------------------------------------------------------------------------
Language                      files          blank        comment           code
--------------------------------------------------------------------------------
Go                             1886          40977          31947         239749
JavaScript                      100          17814           1808          99209
INI                              33           4561           2391          70793
CSS                               2           8569           3276          31452
Markdown                        173           4367              0          20219
JSON                             20              8              0          18499
Properties                      123           2117           7980          15390
LESS                             42           1694            122           9141
YAML                             96            686            106           8959
SVG                             366              1              2            897
make                              3            202             11            805
Vuejs Component                   7             86             48            802
Bourne Shell                     20            121            132            469
HTML                              7             52             17            390
Bourne Again Shell               22             45             36            239
Dockerfile                        2             30             12             99
XML                               2              6              7             72
diff                              1              7             15             17
TOML                              1              1              0              9
SQL                               1              0              0              2
--------------------------------------------------------------------------------
SUM:                           2907          81344          47910         517212
--------------------------------------------------------------------------------

Of those 520 000 lines, I estimate that 100 000-250 000 lines would need to be changed for your approach.
Do you see what I mean, when I say it's unlikely to be implemented completely?

@delvh commented on GitHub (Nov 29, 2022): I agree to some extent: Yes, I also think it is a good idea to use the UI as API where possible, however, there would be **a lot** of work to implement this completely: Our UI routes are constantly updated, and are not backward compatible. With this approach, they would need to be. Then, our UI is currently rendered mostly through Go templates. Changing all that is **a lot** of work, as that will basically amount to rewriting the entire frontend. Furthermore, by moving away from Go templates we would lose the amount of customizability that is currently possible. I did not even touch the topic of JS being disabled, or requests going missing yet: With your proposed approach, those concerns must also be answered, even though developers like to assume they are not there. Lastly, there is **a lot** of UI-specific code explicitly tailored for the UI inside the backend. That would again be **really hard** to change. cloc currently produces the following: ```bash 4391 text files. 2907 unique files. 1502 files ignored. 1 error: Line count, exceeded timeout: routers/web/web.go github.com/AlDanial/cloc v 1.94 T=5.15 s (564.9 files/s, 125627.9 lines/s) -------------------------------------------------------------------------------- Language files blank comment code -------------------------------------------------------------------------------- Go 1886 40977 31947 239749 JavaScript 100 17814 1808 99209 INI 33 4561 2391 70793 CSS 2 8569 3276 31452 Markdown 173 4367 0 20219 JSON 20 8 0 18499 Properties 123 2117 7980 15390 LESS 42 1694 122 9141 YAML 96 686 106 8959 SVG 366 1 2 897 make 3 202 11 805 Vuejs Component 7 86 48 802 Bourne Shell 20 121 132 469 HTML 7 52 17 390 Bourne Again Shell 22 45 36 239 Dockerfile 2 30 12 99 XML 2 6 7 72 diff 1 7 15 17 TOML 1 1 0 9 SQL 1 0 0 2 -------------------------------------------------------------------------------- SUM: 2907 81344 47910 517212 -------------------------------------------------------------------------------- ``` Of those 520 000 lines, I estimate that 100 000-250 000 lines would need to be changed for your approach. Do you see what I mean, when I say it's unlikely to be implemented completely?
Author
Owner

@pboguslawski commented on GitHub (Nov 29, 2022):

Do you see what I mean, when I say it's unlikely to be implemented completely?

Yes I'm aware of complexity of such changes in existing projects; consider evolution (implementing changes according to ordered direction) not revolution. Your stat shows many technologies (not all probably - many different UI frameworks used?) which looks hard to manitain and probably will be harder to maintain/modernize in the future if changes will be required (i.e. dropping outdated frameworks). Maintaining one API will be easier from security perspective also problably.

@pboguslawski commented on GitHub (Nov 29, 2022): > Do you see what I mean, when I say it's unlikely to be implemented completely? Yes I'm aware of complexity of such changes in existing projects; consider evolution (implementing changes according to ordered direction) not revolution. Your stat shows many technologies (not all probably - many different UI frameworks used?) which looks hard to manitain and probably will be harder to maintain/modernize in the future if changes will be required (i.e. dropping outdated frameworks). Maintaining one API will be easier from security perspective also problably.
Author
Owner

@lunny commented on GitHub (Nov 30, 2022):

I think the API should be a standalone service which main aim is to be invoked by external tools like sdks, CI/CD, mobile etc. which need a stable output. But for UI, the requirement is to provide data according the UI need, it means they should be changed when UI changed as well. So I don't think they should be shared otherwise it will bondage UI's development, you need to consider more when you want to change some routes.

For the SPA idea, for a very big project, a single page SPA will slow down the loading speed in an internet environment. Since Gitea wants to support both internet instances and intranet instances, at least we need a multiple page SPA. Go templates required some skills for frontend developers but an advantage of that is SEO, that is important for public Gitea instances.

@lunny commented on GitHub (Nov 30, 2022): I think the API should be a standalone service which main aim is to be invoked by external tools like sdks, CI/CD, mobile etc. which need a stable output. But for UI, the requirement is to provide data according the UI need, it means they should be changed when UI changed as well. So I don't think they should be shared otherwise it will bondage UI's development, you need to consider more when you want to change some routes. For the SPA idea, for a very big project, a single page SPA will slow down the loading speed in an internet environment. Since Gitea wants to support both internet instances and intranet instances, at least we need a multiple page SPA. Go templates required some skills for frontend developers but an advantage of that is SEO, that is important for public Gitea instances.
Author
Owner

@techknowlogick commented on GitHub (Nov 30, 2022):

You may be interested in the following: https://github.com/unfoldingWord/gitea-react-toolkit

@techknowlogick commented on GitHub (Nov 30, 2022): You may be interested in the following: https://github.com/unfoldingWord/gitea-react-toolkit
Author
Owner

@kousu commented on GitHub (Dec 1, 2022):

I would not like Gitea to be an SPA. I like that it renders, tight, low-resource HTML and is usable without JavaScript.

Making an SPA would mean adding way more network traffic to compute basic facts; like, how would you implement this typesniffer in an SPA?

b2c4870481/routers/web/repo/view.go (L385-L388)

b2c4870481/routers/web/repo/view.go (L608-L616)

b2c4870481/templates/repo/view_file.tmpl (L63-L84)

You'd have to download and parse the files in JavaScript, or fallback on trusting their file extensions, or add "/type-sniff/" route.

So, sorry, and I'm not on the team so my vote doesn't count for much, but 👎

@kousu commented on GitHub (Dec 1, 2022): I would not like Gitea to be an SPA. I like that it renders, tight, low-resource HTML and is usable without JavaScript. Making an SPA would mean adding way more network traffic to compute basic facts; like, how would you implement this typesniffer in an SPA? https://github.com/go-gitea/gitea/blob/b2c4870481329889a76ea2421152647d36dd8374/routers/web/repo/view.go#L385-L388 https://github.com/go-gitea/gitea/blob/b2c4870481329889a76ea2421152647d36dd8374/routers/web/repo/view.go#L608-L616 https://github.com/go-gitea/gitea/blob/b2c4870481329889a76ea2421152647d36dd8374/templates/repo/view_file.tmpl#L63-L84 You'd have to download and parse the files in JavaScript, or fallback on trusting their file extensions, or add "/type-sniff/" route. So, sorry, and I'm not on the team so my vote doesn't count for much, but :-1:
Author
Owner

@pboguslawski commented on GitHub (Dec 1, 2022):

which need a stable output

Yes API should be stable but can be extended in backward compatible way. Breaking changes should increment API major version similar to how go modules versioning works.

But for UI, the requirement is to provide data according the UI need,

Web UI should be treated as any other client and Web UI specific processing should be moved to Web UI if possible not to API. API should be kept as minimal, common base required for any type of client to be able to function.

otherwise it will bondage UI's development,

Adding features should be analyzed on both sides: API and client; if its possible to implement feature easily on client side only - API should not be extended (to keep is as simple and secure as possible). Also bloatware direction should be avoided.

For the SPA idea, for a very big project, a single page SPA will slow down the loading speed in an internet environment.

at least we need a multiple page SPA

but an advantage of that is SEO, that is important for public Gitea instances.

This is challenge I agree. Github.com direction worth studying here maybe; mutliple SPAs will be better than server side rendering IHMO. Client/API separation would help in experiments with different client technologies and even provide seaparate clients for different areas (i.e. dummy front for search engines that won't read SPA, light HTML front for people afraid of JS, main modern UI with JS/wasm for general use, etc.).

how would you implement this typesniffer in an SPA

Don't know this function but well designed API should not trust any client, even its own web UI and verify incoming every data on backed before storing/applying it to system. Verification on client side may be helpful also to avoid long uploads just to be blocked by server.

@pboguslawski commented on GitHub (Dec 1, 2022): > which need a stable output Yes API should be stable but can be extended in backward compatible way. Breaking changes should increment API major version similar to how go modules versioning works. > But for UI, the requirement is to provide data according the UI need, Web UI should be treated as any other client and Web UI specific processing should be moved to Web UI if possible not to API. API should be kept as minimal, common base required for any type of client to be able to function. > otherwise it will bondage UI's development, Adding features should be analyzed on both sides: API and client; if its possible to implement feature easily on client side only - API should not be extended (to keep is as simple and secure as possible). Also [bloatware](https://en.wikipedia.org/wiki/Software_bloat#Examples) direction should be avoided. > For the SPA idea, for a very big project, a single page SPA will slow down the loading speed in an internet environment. > at least we need a multiple page SPA > but an advantage of that is SEO, that is important for public Gitea instances. This is challenge I agree. Github.com direction worth studying here maybe; mutliple SPAs will be better than server side rendering IHMO. Client/API separation would help in experiments with different client technologies and even provide seaparate clients for different areas (i.e. dummy front for search engines that won't read SPA, light HTML front for people afraid of JS, main modern UI with JS/wasm for general use, etc.). > how would you implement this typesniffer in an SPA Don't know this function but well designed API should not trust any client, even its own web UI and verify incoming every data on backed before storing/applying it to system. Verification on client side may be helpful also to avoid long uploads just to be blocked by server.
Author
Owner

@gnat commented on GitHub (Dec 6, 2022):

Unnecessary over engineering initiatives will often create a high risk scenario which can be very damaging to any project:

  • Half finished abandoned efforts resulting in a split, unmaintainable architecture;
  • Suffocating development from other more important features;
  • Raising the barrier for contributions to the point where many external contributions dissappear;
  • Adding dependency hell and build time.

If SPA-like functionality could be demonstrably beneficial for certain widgets or pages- I recommend we look at this as an add-on approach, and simply use http://htmx.org on top of what we have and continuing as-is.

Keep it simple. Don't put gitea at risk. The cost of this is far higher than perceived.

@gnat commented on GitHub (Dec 6, 2022): Unnecessary over engineering initiatives will often create a high risk scenario which can be very damaging to any project: * Half finished abandoned efforts resulting in a split, unmaintainable architecture; * Suffocating development from other more important features; * Raising the barrier for contributions to the point where many external contributions dissappear; * Adding dependency hell and build time. If SPA-like functionality could be demonstrably beneficial for certain widgets or pages- I recommend we look at this as an add-on approach, and simply use http://htmx.org on top of what we have and continuing as-is. Keep it simple. Don't put gitea at risk. The cost of this is far higher than perceived.
Author
Owner

@gnat commented on GitHub (Dec 6, 2022):

This is challenge I agree. Github.com direction worth studying here maybe; mutliple SPAs will be better than server side rendering IHMO.

Um, not to make this a red herring, but Github's SPA implementation is notoriously slow compared to accessing Github URL's directly. It's likely Github will eventually move to Hotwire with their Ruby on Rails 7 transition, which is similar to htmx but for Rails 7. I doubt their existing implementation will stick around on the main website.

@gnat commented on GitHub (Dec 6, 2022): > This is challenge I agree. Github.com direction worth studying here maybe; mutliple SPAs will be better than server side rendering IHMO. Um, not to make this a red herring, but Github's SPA implementation is notoriously slow compared to accessing Github URL's directly. It's likely Github will eventually move to Hotwire with their Ruby on Rails 7 transition, which is similar to htmx but for Rails 7. I doubt their existing implementation will stick around on the main website.
Author
Owner

@silverwind commented on GitHub (Apr 26, 2023):

I don't think it's realistic to rewrite Gitea UI to an SPA. Far too much code and far too much work for questionable benefit. Parts of the UI are SPA-fashion components that could also rely on API only, but not everything.

@silverwind commented on GitHub (Apr 26, 2023): I don't think it's realistic to rewrite Gitea UI to an SPA. Far too much code and far too much work for questionable benefit. Parts of the UI are SPA-fashion components that could also rely on API only, but not everything.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/gitea#9908