4coders.net thumbnail
created @09.07.2024
updated @09.07.2024
rustapigwcdksvelte

4coders.net dev tools

While having some time for research and keeping up with tech development, I decided to bootstrap a small website for developer tools.

https://www.4coders.net

The idea is to have a collection of helpful and widely used developer tools. I started with implementing a base64 encoding/decoding and QR code generation functionality. Not very innovative at this point, but it's just the start ;) More things will follow.

4coders.net screenshot

The backend architecture is based on AWS serverless functions written in Rust and compiled to binary to have maximum performance and efficiency.

Frontend is written in SvelteKit.

4coders.net pagespeed4coders.net sequence diagram

Including domain registration, DNS setup, backend infrastructure, implementation of Rust functions for base64 encoding/decoding, frontend bootstrapping and implementation, mobile view, styling, basic SEO setup, I was able to launch the MVP within a day.

To support code reviews and security audits, I received AI support from Claude 3.5 Sonnet ;)

I will update this post while things progress.

created @05.07.2023
updated @05.07.2023
nextjs 13

Refactoring dcshangar.com

  • Next.js App Router
  • React Server Components
dcshangar.com screenshot
created @07.11.2021
updated @08.11.2021
DCSreactawstypescriptnodejsvercelnextjs

Launching dcshangar.com

New Project: dcshangar.com for sharing community content for DCS World.

Features and frameworks

  • multipart upload of screenshots and files
  • download with temporary signed urls
  • auto thumbnail and zip generation
  • auto language detection of text content
  • auto virus check of uploaded files
  • parsing of mission files display of details
  • search and filter settings
  • comments
  • authentication
  • dark mode
  • slack & discord link unfurling
  • websockets for push based client messaging
  • optional short URLs (dcs.rocks) for sharing

Tech Stack

  • react + nextjs 12 deployed via Vercel
  • AWS backend (nodejs, typescript, serverless, aws cdk, 30+ stacks)
  • slack integration for alarming und notifications
  • continuous integration via github actions and Vercel
  • E2E testing with playwright and Saucelabs Cloud
created @31.07.2021
updated @23.12.2022
reactmiddlewareside effectsredux

React Simple Side Effects

https://github.com/christiangoetze/react-simple-side-effects

beforeDispatch(Actions.MY_ACTION_1, () => {
  // do some stuff before state changed
});

afterDispatch(Actions.MY_ACTION_1, () => {
  // do some stuff after state changed
});

afterDispatch<Action1, AppState>(Actions.MY_ACTION_1, ({action, oldState, newState}) => {
  // access action or state
  console.log(action.payload, oldState, newState);
});

afterDispatch(Actions.MY_ACTION_1, ({dispatch}) => {
  // dispatch a new action
  dispatch(action2());
});
created @27.07.2020
updated @27.07.2020
sim racinghotlap_ggproject cars 2

Launching hotlap.gg

After some development time, one of my side projects is now going live. hotlap.gg – Sim racing setups

A web app that offers setups for various sim racing games.

Currently reduced to Project Cars 2 and basic functions such as create and search, many features will follow in the next few months.

created @25.05.2020
updated @25.05.2020
google page speedchrome audit

PageSpeed :P

After some optimizations, the results are quite satifying.

Thx @aws and @angular

created @28.10.2017
updated @16.08.2019
angularawss3cloudfronthosting

Hosting Angular on AWS S3 (using a Strato domain) + ci

Amazon Webservices offers a great option for cheap and ultra fast hosting of a single page app like angular.

Setup AWS S3

  • Create a S3 bucket
  • Enable static website hosting (properties tab in your bucket). Enter index.html as your index and error document.
  • In Permissions->Bucket Policy allow public read access. Insert the following policy inside the statement array of the policy json:
{
  "Sid": "1",
  "Effect": "Allow",
  "Principal": "*",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME_HERE/*"
}

Setup AWS Cloudfront

  • create a new web distribution
  • enter your alternate domain names (e.g. cgoetze.de and www.cgoetze.de, one per line)
  • default root object: index.html
  • leave everything else on default
  • once it is created navigate to the origins tab and create a new origin
  • choose your s3 bucket as origin domain name
  • for this tutorial leave 'Restrict Bucket Access' to No, save and exit
  • navigate to the behaviors tab and create a new behavior
  • leave the path pattern to default(*)
  • select the origin we just created, save and exit
  • navigate to the errors tab and create a custom error response. This is a kind of workaroud to map all paths to the index.html
  • select 404: Not Found and select Yes for the customize error response checkbox. Insert /index.html as the response page path and set the status code to 200: OK.

Setup AWS Route53

To map your strato domain to your amazon cloudfront cache, perform the following steps:

  • create a new public hosted zone
  • NS-Name Server and SOA records should be created automatically
  • additionally create an A - IPv4 address record for each domain you want to map
  • enter yourdomain.com as name, for the second A record you may enter www.yourdomain.com
  • enable the Alias checkbox and select Yes
  • the alias target should be your cloudfront url (e.g. xyz123.cloudfront.net.) With a trailing dot.
  • select routing policy Simple

Setup Strato DNS record

  • redirect your domain to the www. subdomain. (e.g. cgoetze.de is redirected to www.cgoetze.de with external http redirection)
  • open the dns management of your www subdomain
  • add a new ns record and insert all four route 53 name servers which are display in the ns record we created in route 53. Insert them with the trailing dot at the end.
  • apply the changes and thats it for the most complicated part of this tutorial
  • be aware that dns changes of strato and route53 can take some time before they are distributed across all parties

Setup Angular project

  • create the following buildspec.yml file in the top level directory of your angular cli project
version: 0.2
env:
  variables:
      S3_BUCKET: "YOUR_BUCKET_NAME_HERE" <- only the bucket name, not the full path
phases:
  install:
    commands:
      - npm i
  build:
    commands:
      - npm run build-prod
  post_build:
    commands:
      - aws s3 cp dist s3://${S3_BUCKET} --recursive
artifacts:
  files:
    - '**/*'
  base-directory: 'dist'
  • note the build-prod script under build->commands of the buildspec file. This a script i defined in my package.json which basically executes ng build --prod

Setup CI with AWS Codebuild

  • create a new aws code build project
  • for angular i choose the nodejs 7 image
  • as artifact type choose No Artifacts. Because you want to copy the files to the s3 bucket top level directory as defined in the buildspec.yml, we don't need to define an artifact here. If you select folder, then we will end up with a subfolder in our s3 bucket which will cause us some problems when using the static site hosting.
created @04.02.2017
updated @16.08.2019
contentfulangular2typescript

Creating a simple Angular contentful service

Now we're going to create a simple angular service to fetch data from contentfuls api.

First, let's create a contentful.service.ts

import { Injectable } from '@angular/core';
import { Observable, from } from 'rxjs';
import * as contentful from 'contentful';
import { ContentfulEntries } from './contentful-entries.model';

@Injectable()
export class ContentfulService {
  private readonly client: any;

  constructor() {
    this.client = contentful.createClient({
      space: '...',
      accessToken: '...'
    });
  }

  getAllEntriesByContentType(contentType: string): Observable<ContentfulEntries> {
    return from(this.client.getEntries({ 
      content_type: contentType 
    }) as Promise<ContentfulEntries>);
  }
}

When querying the contentful entries endpoint we get the following response.

Notice: Everything inside "fields" is custom content model structure.

(I removed nonrelevant parts)

{
  ...
  "items": [
    {
      "sys": {
        ...,
        "updatedAt": "2017-02-05T09:00:39.151Z",
        ...
      },
      "fields": {
        "title": "Creating a simple Angular2 contentful service",
        "text": ...,
        "image": ...,
        "authors": [
          "Christian"
        ],
        "tags": [
          "contentful",
          "angular2",
          "typescript"
        ]
      }
    }
  ],
  "includes": {
    ...
  }
}

To work with this response, let's create some models the angular way;

contentful-entries.model.ts

import { ContentfulItem, ContentfulInclude } from './';

export class ContentfulEntries {
    items: ContentfulItem[];
    includes: ContentfulInclude[];
}

contentful-item.model.ts

export class ContentfulItem {
    sys: any;
    fields: any;
}