Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What about going Jamstack? #21977

Closed
pboguslawski opened this issue Nov 29, 2022 · 9 comments
Closed

What about going Jamstack? #21977

pboguslawski opened this issue Nov 29, 2022 · 9 comments
Labels
type/proposal The new feature has not been accepted yet but needs to be discussed first.

Comments

@pboguslawski
Copy link
Contributor

Feature Description

#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

@pboguslawski pboguslawski added type/feature Completely new functionality. Can only be merged if feature freeze is not active. type/proposal The new feature has not been accepted yet but needs to be discussed first. labels Nov 29, 2022
@delvh
Copy link
Member

delvh commented 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?

@pboguslawski
Copy link
Contributor Author

pboguslawski commented 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.

@lunny
Copy link
Member

lunny commented 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 lunny removed the type/feature Completely new functionality. Can only be merged if feature freeze is not active. label Nov 30, 2022
@techknowlogick
Copy link
Member

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

@kousu
Copy link
Contributor

kousu commented 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?

n, _ := util.ReadAtMost(dataRc, buf)
buf = buf[:n]
st := typesniffer.DetectContentType(buf)

case st.IsPDF():
ctx.Data["IsPDFFile"] = true
case st.IsVideo():
ctx.Data["IsVideoFile"] = true
case st.IsAudio():
ctx.Data["IsAudioFile"] = true
case st.IsImage() && (setting.UI.SVG.Enabled || !st.IsSvgImage()):
ctx.Data["IsImageFile"] = true
ctx.Data["CanCopyContent"] = true

{{if .IsMarkup}}
{{if .FileContent}}{{.FileContent | Safe}}{{end}}
{{else if .IsRenderedHTML}}
<pre>{{if .FileContent}}{{.FileContent | Str2html}}{{end}}</pre>
{{else if not .IsTextSource}}
<div class="view-raw ui center">
{{if .IsImageFile}}
<img src="{{$.RawFileLink}}">
{{else if .IsVideoFile}}
<video controls src="{{$.RawFileLink}}">
<strong>{{.locale.Tr "repo.video_not_supported_in_browser"}}</strong>
</video>
{{else if .IsAudioFile}}
<audio controls src="{{$.RawFileLink}}">
<strong>{{.locale.Tr "repo.audio_not_supported_in_browser"}}</strong>
</audio>
{{else if .IsPDFFile}}
<iframe width="100%" height="600px" src="{{AssetUrlPrefix}}/vendor/plugins/pdfjs/web/viewer.html?file={{$.RawFileLink}}"></iframe>
{{else}}
<a href="{{$.RawFileLink}}" rel="nofollow" class="btn btn-gray btn-radius">{{.locale.Tr "repo.file_view_raw"}}</a>
{{end}}
</div>

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 👎

@pboguslawski
Copy link
Contributor Author

pboguslawski commented 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.

@gnat
Copy link
Contributor

gnat commented 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
Copy link
Contributor

gnat commented 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.

@silverwind
Copy link
Member

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 11, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type/proposal The new feature has not been accepted yet but needs to be discussed first.
Projects
None yet
Development

No branches or pull requests

7 participants