Developer Blog

Tipps und Tricks für Entwickler und IT-Interessierte

Ollama | Create a ChatGPT Clone with Ollama and HyperDiv

In this blog post, we’ll explore how to create a ChatGPT-like application using Hyperdiv and Ollama. Hyperdiv provides a flexible framework for building web applications, while Ollama offers powerful local machine learning capabilities.

We will start with the Hyperdiv GPT-chatbot app template and adapt it to leverage Ollama, which runs locally. This guide will walk you through the necessary steps and code changes to integrate these technologies effectively.

TL;DR

The complete code for this tutorial is here.

Step 1: Setting Up Your Environment

Install Ollama

Download Ollama from https://ollama.com/download.

Install (Windows) or unpack (macOS) the downloaded file. This gets you an Ollama app (which allows you to start the Ollama service) and a Ollama command line.

Start the Ollama service by starting the Ollama app.

On macOS, you will see an icon for the Ollama Servce at the top bar.

Then, open a terminal and type ollama list. This command displays the install models.

ollama list

To install a model, type

ollama pull llama3

For our ChatGPT Clone, we will use the llama3 model.

If you want to use another model, then search here: https://ollama.com/library

Clone the HyperDiv Examples Repository

Start by cloning or downloading the Hyperdiv GPT-chatbot app. This app provides a basic structure for a chatbot application, which we will modify to work with Ollama.

Go to your desired local folder to store the sources and type

git clone https://github.com/hyperdiv/hyperdiv-apps

Then, go to the folder hyperdiv-apps/gpt-chatbot

Adapt app to use Ollama backend

First, we will create an ollama client to process all request:

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:11434/v1",
    api_key="ollama",
)

Then we modify the request function to use this client

We change

response = openai.ChatCompletion.create(

to

response = client.chat.completions.create(

Next step is changing the accees to the response fields. With OpenAI, the response data is a dictionary, so the way to acess the fields is like

chunk["choices"]

With Ollama, we can access the field by name

chunk.choices

The changes are

 for chunk in response:
    message = chunk.choices[0].delta
    state.current_reply += message.content

And the last step would be the change to use the correct model:

model = form.select(
    options=("codellama", "llama2", "llama3", "mistral"),
        value="llama3",
        name="gpt-model",
)

Thats is! Save all changes

Prepare Python environment and run app

Install the required modules:

pip install openai hyperdiv

Run the app:

python start.py

Open the browser at http://localhost:8888

Final Result

The complete code for this tutorial is here.

Learning | Hello World in different Languages

Python

print("Hello, World!")

Java

public class HelloWorld {
    public static void main(String[] args) {
        System out println("Hello, World!");
    }
}

C

#include <stdio h>

int main() {
    printf("Hello, World!\n");
    return 0;
}

C++:

#include <iostream>

int main() {
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

JavaScript

console log("Hello, World!");

Ruby

puts "Hello, World!"

Swift

print("Hello, World!")

Go

package main

import "fmt"

func main() {
    fmt Println("Hello, World!")
}

Rust

fn main() {
    println!("Hello, World!");
}

PHP

<?php
echo "Hello, World!";
?>

Perl

print "Hello, World!\n";

Kotlin

fun main() {
    println("Hello, World!")
}

Scala

object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello, World!")
  }
}

Lua

print("Hello, World!")

Haskell

main :: IO ()
main = putStrLn "Hello, World!"

Dart

void main() {
  print('Hello, World!');
}

Shell

echo "Hello, World!"

Batch

@echo off
echo Hello, World!

PowerShell

Write-Output "Hello, World!"

VBScript

MsgBox "Hello, World!"

Objective-C

#import <Foundation/Foundation h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSLog(@"Hello, World!");
    }
    return 0;
}

Assembly

section  data
    hello db 'Hello, World!',10
    len equ $ - hello

section  text
    global _start

_start:
    ; write our string to stdout
    mov eax, 4         ; sys_write
    mov ebx, 1         ; file descriptor 1 (stdout)
    mov ecx, hello     ; message to write
    mov edx, len       ; message length
    int 0x80           ; syscall
    ; exit
    mov eax, 1         ; sys_exit
    xor ebx, ebx       ; exit status 0
    int 0x80           ; syscall

VBA (Visual Basic for Applications)

Sub HelloWorld()
    MsgBox "Hello, World!"
End Sub

Tcl

puts "Hello, World!"

COBOL

       IDENTIFICATION DIVISION 
       PROGRAM-ID  HELLO-WORLD 
       PROCEDURE DIVISION 
           DISPLAY "Hello, World!" 
           STOP RUN 

26 F#:

printfn "Hello, World!"

Elixir

IO puts "Hello, World!"

SQL (MySQL)

SELECT 'Hello, World!';

SQL (SQLite)

SELECT 'Hello, World!';

SQL (PostgreSQL)

SELECT 'Hello, World!';

SQL (Oracle)

SELECT 'Hello, World!' FROM DUAL;

SQL (SQL Server)

PRINT 'Hello, World!';

Smalltalk

Transcript show: 'Hello, World!'; cr 

R

cat("Hello, World!\n")

Bash

echo "Hello, World!"

Erlang

-module(hello) 
-export([hello_world/0]) 

hello_world() ->
    io:fwrite("Hello, World!~n") 

Julia

println("Hello, World!")

MATLAB

disp('Hello, World!');

AutoHotkey

MsgBox, Hello, World!

Clojure

(println "Hello, World!")

Groovy

println "Hello, World!"

OCaml

print_endline "Hello, World!"

D

import std stdio;

void main()
{
    writeln("Hello, World!");
}

Crystal

puts "Hello, World!"

Nim

echo "Hello, World!"

Common Lisp

(format t "Hello, World!



Scheme

(display "Hello, World!")
(newline)

Prolog

:- initialization(main) 

main :-
    write('Hello, World!'), nl,
    halt 

ABAP

REPORT ZHELLO_WORLD 

WRITE: / 'Hello, World!' 

VB NET

vb net
Module HelloWorld
    Sub Main()
        Console WriteLine("Hello, World!")
    End Sub
End Module 

AI Environment | Writing Apps for OpenAI, ChatGPT, Ollama and others

Python UI Frameworks

  • Gradio
    Gradio is the fastest way to demo your machine learning model with a friendly web interface so that anyone can use it, anywhere!
  • Streamlit
    Streamlit turns data scripts into shareable web apps in minutes.
    All in pure Python. No front‑end experience required.
  • HyperDiv
    Open-source framework for rapidly building reactive web apps in Python, with built-in Shoelace components, Markdown, charts, tables, and more.
  • Shoelace
    A forward-thinking library of web components.

Ollama | Getting Started

Installation

Read here for details.

Linuxcurl -fsSL https://ollama.com/install.sh | sh
Mac OSDownload
WindowsDownload

Start Ollama Service

ollama start

This starts the Ollama Service and binds it to the default ip address 127.0.0.1:11434

If you want to access the service from another host/client, you have to use the ip address 0.0.0.0

systemctl stop ollama.service
export OLLAMA_HOST=0.0.0.0:11434
ollama start

To change the IP address of the service, edit the file /etc/systemd/system/ollama.service and add

[Unit]
Description=Ollama Service
After=network-online.target

[Service]
ExecStart=/usr/local/bin/ollama serve
User=ollama
Group=ollama
Restart=always
RestartSec=3
Environment="OLLAMA_HOST=0.0.0.0:11434"

[Install]
WantedBy=default.target

Access the Ollama Service from your Browser using <ip-adress of host>:11434

Sample Python Chat

Install Python

Install Ollama Library

pip install ollama

Create the chat programm

#!/usr/bin/env python

from ollama import Client

ollama = Client(host='127.0.0.1')

response = ollama.chat(model='llama3', messages=[
  {
    'role': 'user',
    'content': 'Why is the sky blue?',
  },
])
print(response['message']['content'])

Run the programm

❯ ./chat.py

Hint: To see, whats happen with the service, monitor the logfile

❯ sudo journalctl -u ollama.service -f

Query the API

Read the API definition here

curl http://localhost:11434/api/generate -d '{
  "model": "llama2",
  "prompt": "Why is the sky blue?",
  "stream": false
}'

Create a simple ChatGPT Clone

Create the Gradio App

Gatsby | Getting started with Gatsby

Installation

npm init gatsby
pnpm create gatsby
❯ npm create gatsby
.../21.6.2/pnpm/store/v3/tmp/dlx-42253   |   +3 +
.../21.6.2/pnpm/store/v3/tmp/dlx-42253   | Progress: resolved 3, reused 1, downloaded 2, added 3, done
create-gatsby version 3.13.1

                                                                            Welcome to Gatsby!
What would you like to call your site?
✔ Getting-Started-with-Gatsby/ site
✔ Will you be using JavaScript or TypeScript?
· TypeScript
✔ Will you be using a CMS?
· No (or I'll add it later)
✔ Would you like to install a styling system?
· Tailwind CSS
✔ Would you like to install additional features with other plugins?
· Add responsive images
· Add an automatic sitemap
· Generate a manifest file
· Add Markdown and MDX support


Thanks! Here's what we'll now do:

    🛠  Create a new Gatsby site in the folder site
    🎨 Get you set up to use Tailwind CSS for styling your site
    🔌 Install gatsby-plugin-image, gatsby-plugin-sitemap, gatsby-plugin-manifest, gatsby-plugin-mdx

✔ Shall we do this? (Y/n) · Yes
✔ Created site from template
✔ Installed Gatsby
✔ Installed plugins
✔ Created site in site
🔌 Setting-up plugins...
info Adding gatsby-plugin-postcss
info Adding gatsby-plugin-image
info Adding gatsby-plugin-sitemap
info Adding gatsby-plugin-manifest
info Adding gatsby-plugin-mdx
info Adding gatsby-plugin-sharp
info Adding gatsby-transformer-sharp
info Adding gatsby-source-filesystem
info Adding gatsby-source-filesystem
info Installed gatsby-plugin-postcss in gatsby-config
success Adding gatsby-plugin-postcss to gatsby-config - 0.224s
info Installed gatsby-plugin-image in gatsby-config
success Adding gatsby-plugin-image to gatsby-config - 0.221s
info Installed gatsby-plugin-sitemap in gatsby-config
success Adding gatsby-plugin-sitemap to gatsby-config - 0.230s
info Installed gatsby-plugin-manifest in gatsby-config
success Adding gatsby-plugin-manifest to gatsby-config - 0.258s
info Installed gatsby-plugin-mdx in gatsby-config
success Adding gatsby-plugin-mdx to gatsby-config - 0.264s
info Installed gatsby-plugin-sharp in gatsby-config
success Adding gatsby-plugin-sharp to gatsby-config - 0.265s
info Installed gatsby-transformer-sharp in gatsby-config
success Adding gatsby-transformer-sharp to gatsby-config - 0.269s
info Installed gatsby-source-filesystem in gatsby-config
success Adding gatsby-source-filesystem (images) to gatsby-config - 0.279s
info Installed gatsby-source-filesystem in gatsby-config
success Adding gatsby-source-filesystem (pages) to gatsby-config - 0.286s
🎨 Adding necessary styling files...
🎉  Your new Gatsby site Getting Started with Gatsby has been successfully created
at /Users/Shared/CLOUD/Programmier-Workshops/Kurse/Gatsby/Einsteiger/Getting-Started-with-Gatsby/site.
Start by going to the directory with

  cd site

Start the local development server with

  npm run develop

See all commands at

  https://www.gatsbyjs.com/docs/reference/gatsby-cli/
❯ cd site
❯ npm install
❯ npm run develop

PHP | Ökosystem

PHPStan

Finds bugs in your code without writing tests. It’s open-source and free.

PHPMD: PHP Mess Detector

What PHPMD does is: It takes a given PHP source code base and look for several potential problems within that source. These problems can be things like:

  • Possible bugs
  • Suboptimal code
  • Overcomplicated expressions
  • Unused parameters, methods, properties

PHPMD is a mature project and provides a diverse set of pre defined rules (though may be not as many its Java brother PMD) to detect code smells and possible errors within the analyzed source code. Checkout the rules section to learn more about all implemented rules.

PHP CodeSniffer

PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.

GrumPHP

Sick and tired of defending code quality over and over again? GrumPHP will do it for you! This composer plugin will register some git hooks in your package repository. When somebody commits changes, GrumPHP will run some tests on the committed code. If the tests fail, you won’t be able to commit your changes. This handy tool will not only improve your codebase, it will also teach your co-workers to write better code following the best practices you’ve determined as a team.

https://api-platform.com

Laravel | Arbeiten mit Swagger

Schritt 1: Erstellen Sie ein Laravel-Projekt

Wenn Sie noch kein Laravel-Projekt haben, erstellen Sie eines mit Composer. Öffnen Sie Ihr Terminal und führen Sie den folgenden Befehl aus:

composer create-project --prefer-dist laravel/laravel App

Ersetzen Sie your-api-project durch den gewünschten Projektnamen.

Schritt 2: Installieren Sie die Swagger-PHP-Bibliothek

Sie benötigen die Swagger-PHP-Bibliothek, um Swagger-Dokumentation zu generieren. Installieren Sie diese mit Composer:

composer require zircote/swagger-php

Schritt 3: Erstellen Sie API-Routen

In Laravel definieren Sie Ihre API-Routen in der Datei routes/api.php. Sie können Routen erstellen, wie Sie es normalerweise für Ihre API tun würden.

routes/api.php

use Illuminate\Support\Facades\Route;

Route::get('/users', 'UserController@index');
Route::post('/users', 'UserController@store');
Route::get('/users/{id}', 'UserController@show');

Schritt 4: Generieren Sie Swagger-Annotationen

In Ihren Controller-Methoden verwenden Sie Swagger-Annotationen, um Ihre API zu dokumentieren. Hier ist ein Beispiel, wie man eine Controller-Methode annotiert:

/**
 * @SWG\Get(
 *     path="/users",
 *     summary="Holt eine Liste von Benutzern",
 *     tags={"Users"},
 *     @SWG\Response(response=200, description="Erfolgreiche Operation"),
 *     @SWG\Response(response=400, description="Ungültige Anfrage")
 * )
 */
public function index()
{
    // Ihre API-Logik hier
}

Weitere Informationen zu Swagger-Annotationen finden Sie in der Swagger-PHP-Dokumentation.

Schritt 5: Generieren Sie Swagger-Dokumentation

Nachdem Sie Ihre Controller annotiert haben, müssen Sie die Swagger-Dokumentation generieren. Dies können Sie mit dem artisan Befehl tun, der vom darkaonline/l5-swagger Paket bereitgestellt wird.

Zuerst installieren Sie das Paket:

composer require darkaonline/l5-swagger

Veröffentlichen Sie nun die Swagger-Konfiguration:

php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider"

Bearbeiten Sie die Datei config/l5-swagger.php, um die Swagger-Konfiguration nach Bedarf anzupassen.

Schritt 6: Generieren Sie Swagger-Dokumentation

Führen Sie den folgenden Befehl aus, um die Swagger-Dokumentation zu generieren:

php artisan l5-swagger:generate

Die Swagger UI ist verfügbar unter http://127.0.0.1:8000/api/documentation.

Schritt 7: Zugriff auf Swagger UI

Öffnen sie die Swagger UI URL in Ihrem Browser.

Laravel | Erstellen eines API Backend

TL;DR

Der Code für die in diesem Post erstelle Anwendung liegt hier.

Notwendige Komponenten eines API Backend

Für die Umsetzung eines API Backend benötigen wir in unserer Laravel App mehrere Komponenten:

  • ein Model, das beschreibt, wir die Daten aussehen, die unsere API verwendet
  • ein Controller, der den Programmcode beinhaltet, m die einzelnen Aktionen (Create, Read, Update, Delete, ..) auszuführen
  • weitere Komponenten, um die Nutzung zu erleichern
    • ein Seeder um die Datenbank mit definierte Werten zu füllen
    • ein Migrationsskript, um die notwendigen Datenbankeinträge (Tabelle, Spalten) zu erstellen
    • Testskripte, um unseren Controller und weitere Kompoentne zu prüfen

Hinweis

Vorab ein Hinweis: jeder der nachfolgenden Kommandos erstellen Komponenten in Form von Dateien. Ein erneutes Erstellen wird fehlschlagen, da die entsprechende Datei schon vorhanden ist.

Um mit den verschiedenen Kommandos zu experimentieren, verwenden sie am besten eine Funktionalität von Git, die es ihnen ermöglicht de Status zurückzusetzen, also Dateien zu löschen.

Wenn Sie ein Kommando ausgeführt haben, dann sehen sie im Visual Studio die neu erstellen Dateien:

Selektieren sie die neu erstellten Dateien und wählen sie dann die Option Discard Changes:

Komponenten erstellen

Jede dieser Komponenten kann einzeln erstellt werden, z. B mit

❯ php artisan make:model Post
❯ php artisan make:controller PostController

Hierbei gilt es natürlich, die Abhängigkeiten zu berücksichtigen. Der Controller muss mit dem Model arbeiten und sollte daher die gleichen Felder und Feldnamen verwendet.

Einfacher ist es daher, das Laravel diese Abhängigkeiten kennt und entsprechend verwendet.

Bei der Erstellung des Models können wir auch einen dazu passenden Controller und weitere Komponenten erstellen:

❯ php artisan make:model Post --migration --controller --seed --api --requests --pest

   INFO  Model and test [app/Models/Post.php] created successfully.
   INFO  Migration [database/migrations/2024_04_19_073500_create_posts_table.php] created successfully.
   INFO  Seeder [database/seeders/PostSeeder.php] created successfully.
   INFO  Request [app/Http/Requests/StorePostRequest.php] created successfully.
   INFO  Request [app/Http/Requests/UpdatePostRequest.php] created successfully.
   INFO  Controller and test [app/Http/Controllers/PostController.php] created successfully.

Dies erstellt die Dateien

	app/Http/Controllers/PostController.php
	app/Http/Requests/
	app/Models/Post.php
	database/migrations/2024_04_19_073500_create_posts_table.php
	database/seeders/PostSeeder.php
	tests/Feature/Http/
	tests/Feature/Models/

Und um alle möglichen Komponenten zu erstellen, verwenden wir den nachfolgenden Befehl:

❯ php artisan make:model Post --all --pest

   INFO  Model and test [app/Models/Post.php] created successfully.
   INFO  Factory [database/factories/PostFactory.php] created successfully.
   INFO  Migration [database/migrations/2024_04_19_073800_create_posts_table.php] created successfully.
   INFO  Seeder [database/seeders/PostSeeder.php] created successfully.
   INFO  Request [app/Http/Requests/StorePostRequest.php] created successfully.
   INFO  Request [app/Http/Requests/UpdatePostRequest.php] created successfully.
   INFO  Controller and test [app/Http/Controllers/PostController.php] created successfully.
   INFO  Policy [app/Policies/PostPolicy.php] created successfully.

Dies erstellt die Dateien

	app/Http/Controllers/PostController.php
	app/Http/Requests/
	app/Models/Post.php
	app/Policies/PostPolicy.php
	database/factories/PostFactory.php
	database/migrations/2024_04_19_075242_create_posts_table.php
	database/seeders/PostSeeder.php
	tests/Feature/Http/
	tests/Feature/Models/

Jetzt aber genug der Einführung. Lassen Sie uns mit dem Erstellen des API Backend beginnen.

Sollten Sie Komponentne erstellen haben, dann löschen Sie diese wie beschrieben.

Einrichten der Starter-App

Erstellen der Starter App. In diesem Post beschreibe ich, wie sie eine Starter-App erstellen und die grundlegenden Anpassungen durchführen können.

Sie können die Starter App auch mit dem Laravel-Installer erstellen:

❯ laravel new App   --jet 
                   --api 
                   --database sqlite 
                   --stack livewire  
                   --teams 
                   --dark 
                   --verification 
                   --git 
                   --pest

Oder auch direkt mit dem dazugehörigen Repository starten:

❯ git clone https://github.com/r14r/Laravel_Tutorial_Erstellen-einer-Starter-App App
❯ cd App
❯ composer install
❯ npm install
❯ npm run build
❯ cp .env.example  .env
❯ php artisan migrate
❯ php artisan key:generate
❯ php artisan serve

Erstellen der erforderlichen Komponenten

❯ php artisan make:model Post --all --pest

   INFO  Model and test [app/Models/Post.php] created successfully.
   INFO  Factory [database/factories/PostFactory.php] created successfully.
   INFO  Migration [database/migrations/2024_04_19_075600_create_posts_table.php] created successfully.
   INFO  Seeder [database/seeders/PostSeeder.php] created successfully.
   INFO  Request [app/Http/Requests/StorePostRequest.php] created successfully.
   INFO  Request [app/Http/Requests/UpdatePostRequest.php] created successfully.
   INFO  Controller and test [app/Http/Controllers/PostController.php] created successfully.
   INFO  Policy [app/Policies/PostPolicy.php] created successfully.

Anpassen des Routing

Erweiteren Sie die Datei routes/api.php um den nachfolgenden Programmcode (Zeile 6 und 12-14):

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

use App\Http\Controllers\PostController;

Route::get('/user', function (Request $request) {
    return $request->user();
})->middleware('auth:sanctum');

Route::get('/post',         [PostController::class, 'index']);
Route::post('/post',        [PostController::class, 'store']);
Route::delete('/post/{id}', [PostController::class, 'destroy']);

Prüfen wir die von Laravel erkannten Routen:

Erster Test

Prüfen wir die bisherigen Schritte. Starten sie Laravel und öffnen sie einen Browser unter der Adresse http://127.0.0.1:8000/api/post

❯ php artisan serve

   INFO  Server running on [http://127.0.0.1:8000].

  Press Ctrl+C to stop the server

Sie sehen, das sie nichts sehen. Was zu erwarten war, da die API noch keine Daten hat und daher auch keine Daten liefern kann.

Datenbank

Tabelle erstellen

Erweitern wir als nächstes das Migrations-Skript, um die notwendige Tabelle zu erstellen und mit Werten zu füllen.

Die entsprechende Datei ist

database/migrations/2024_04_19_075600_create_posts_table.php 

Der genaue Name kann dabei bei Ihnen abweichen.

Passen sie die Funktion up() an:

public function up(): void
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('content');
        $table->timestamps();
    });
}

Die neuen Felder werden über eine Migration in der Datenbank erstellt:

❯ php artisan migrate

Wir kontrollieren, ob die Tabelle richtig erstellt wurde:

❯ php artisan db
SQLite version 3.37.0 2021-12-09 01:34:53
Enter ".help" for usage hints.
sqlite> PRAGMA table_info(posts);
0|id|INTEGER|1||1
1|title|varchar|1||0
2|content|TEXT|1||0
3|created_at|datetime|0||0
4|updated_at|datetime|0||0
sqlite> .quit

Tabelle füllen mit Hilfe eines Seeder

Erstellen Sie den Seeder, falls die Datei database/seeders/PostSeeder.php nicht vorhanden ist:

php artisan make:seeder PostSeeder

Ersetzen Sie den Inhalt mit dem nachfolgenden Programmcode:

<?php

namespace Database\Seeders;

use Illuminate\Support\Facades\DB;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class PostSeeder extends Seeder
{
    static $posts = [
        ['title' => 'Summer Health', 'content' => 'Stay hydrated!'],
        ['title' => 'Pasta Recipe',  'content' => 'Tomato base'],
        ['title' => 'Decor Ideas',   'content' => 'Go minimal'],
        ['title' => 'Python Tips',   'content' => 'Use lists']
    ];

    public function run(): void
    {
        foreach (self::$posts as $post) {
            DB::table('posts')->insert([
                'title' => $post['title'], 'content' => $post['content']
            ]);
        }
    }
}

Starten Sie den Seeder:

❯ php artisan db:seed --class PostSeeder

Hinweis: Sie können diesen Seeder auch die den generellen DatabaseSeeder mit aufnehmen, so das der Name des Seeders nicht mit angegeben werden muss.

Fügen die in der Datei database/seeders/DatabaseSeeder.php den nachfolgenden Programmcode hinzu:

$this->call([
    PostSeeder::class,
]);

Starten Sie den Seeder:

❯ php artisan db:seed

Bearbeiten der Komponenten

Model

Erweitern Sie die Datei app/Models/Post.php um die zusätzlichen Felder:

protected $fillable = ['title', 'content', 'created_at', 'updated_at'];

Testing

Für die Operationen GET (Einträge anzeigen), POST (neuen Eintrag erstellen) und DELETE (Eintrag löschen) stehen jeweils eigene URLs zur Verfügung. Am einfachsten ist der Test der URLs mit Postman.

Testen mit Postman

GET

http://127.0.0.1:8000/api/get

POST

http://127.0.0.1:8000/api/post

DELETE

http://127.0.0.1:8000/api/delete/6        

Testen mit curl in der Kommandozeile

GET

❯ curl http://127.0.0.1:8000/api/post
[{"id":1,"title":"Summer Health","content":"Stay hydrated!","created_at":null,"updated_at":null},{"id":2,"title":"Pasta Recipe","content":"Tomato base","created_at":null,"updated_at":null},{"id":3,"title":"Decor Ideas","content":"Go minimal","created_at":null,"updated_at":null},{"id":4,"title":"Python Tips","content":"Use lists","created_at":null,"updated_at":null}]

POST

❯ curl -X POST  http://127.0.0.1:8000/api/post -H "Content-Type: application/json" -d '{ "title": "Neuer Titel", "content": "Neuer Inhalt!" }'
{"title":"Neuer Titel","content":"Neuer Inhalt!","updated_at":"2024-04-19T15:48:22.000000Z","created_at":"2024-04-19T15:48:22.000000Z","id":6}

DELETE

❯ curl -X DELETE http://127.0.0.1:8000/api/post/6
{"message":"Post deleted"}