mirror of
https://github.com/0xShay/halflink.git
synced 2026-01-11 13:13:25 +00:00
Initialise Spring API with ShortLink endpoints
This commit is contained in:
3
backend/.gitignore
vendored
Normal file
3
backend/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
target/
|
||||
|
||||
.idea/
|
||||
50
backend/pom.xml
Normal file
50
backend/pom.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>services.shay</groupId>
|
||||
<artifactId>halflink</artifactId>
|
||||
<version>1.0.0</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>4.0.1</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
<version>3.3.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
21
backend/src/main/java/services/shay/Halflink.java
Normal file
21
backend/src/main/java/services/shay/Halflink.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package services.shay;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@SpringBootApplication
|
||||
public class Halflink {
|
||||
|
||||
@GetMapping("/")
|
||||
String home() {
|
||||
return "Halflink API says hello!";
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Halflink.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package services.shay.shortlink;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public class ShortCodeGenerator {
|
||||
|
||||
private static final String BASE_58_CHARS = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
private static final SecureRandom RANDOM = new SecureRandom();
|
||||
|
||||
public static String generate(int length) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
sb.append(BASE_58_CHARS.charAt(RANDOM.nextInt(BASE_58_CHARS.length())));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String generate() {
|
||||
return "abc";
|
||||
// return generate(7);
|
||||
}
|
||||
|
||||
}
|
||||
58
backend/src/main/java/services/shay/shortlink/ShortLink.java
Normal file
58
backend/src/main/java/services/shay/shortlink/ShortLink.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package services.shay.shortlink;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Null;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "shortlink", uniqueConstraints = { @UniqueConstraint(columnNames = { "code" }) })
|
||||
public class ShortLink {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
@NotNull
|
||||
private String url;
|
||||
|
||||
@NotNull
|
||||
private String title;
|
||||
|
||||
private Date createdAt;
|
||||
|
||||
private Integer clicks;
|
||||
|
||||
private String code;
|
||||
|
||||
protected ShortLink() {}
|
||||
|
||||
public ShortLink(String url, String title) {
|
||||
this.url = url;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@PrePersist
|
||||
protected void onCreate() {
|
||||
createdAt = new Date();
|
||||
clicks = 0;
|
||||
code = ShortCodeGenerator.generate();
|
||||
}
|
||||
|
||||
public UUID getId() { return id; }
|
||||
public String getUrl() { return url; }
|
||||
public String getTitle() { return title; }
|
||||
public Date getCreatedAt() { return createdAt; }
|
||||
public Integer getClicks() { return clicks; }
|
||||
public String getCode() { return code; }
|
||||
|
||||
public void setId(UUID id) { this.id = id; }
|
||||
public void setUrl(String url) { this.url = url; }
|
||||
public void setTitle(String title) { this.title = title; }
|
||||
public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; }
|
||||
public void setClicks(Integer clicks) { this.clicks = clicks; }
|
||||
public void setCode(String code) { this.code = code; }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package services.shay.shortlink;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.UUID;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/sl")
|
||||
public class ShortLinkController {
|
||||
|
||||
private final ShortLinkRepository shortLinkRepository;
|
||||
|
||||
public ShortLinkController(ShortLinkRepository shortLinkRepository) {
|
||||
this.shortLinkRepository = shortLinkRepository;
|
||||
}
|
||||
|
||||
@GetMapping("/{code}")
|
||||
public ResponseEntity<Void> redirectToUrl(@PathVariable String code) {
|
||||
ShortLink sl = shortLinkRepository.findByCode(code).orElse(null);
|
||||
if (sl != null) {
|
||||
sl.setClicks(sl.getClicks() + 1);
|
||||
shortLinkRepository.save(sl);
|
||||
return ResponseEntity
|
||||
.status(HttpStatus.FOUND)
|
||||
.location(URI.create(sl.getUrl()))
|
||||
.build();
|
||||
}
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ShortLink createShortLink(@Valid @RequestBody ShortLink shortLink) {
|
||||
ShortLink savedShortLink = shortLinkRepository.save(shortLink);
|
||||
System.out.println("savedShortLink = " + savedShortLink);
|
||||
return savedShortLink;
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public void deleteShortLink(@PathVariable UUID id) {
|
||||
shortLinkRepository.deleteById(id);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package services.shay.shortlink;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface ShortLinkRepository extends JpaRepository<ShortLink, UUID> {
|
||||
|
||||
Optional<ShortLink> findByCode(String code);
|
||||
|
||||
}
|
||||
8
backend/src/main/resources/application.properties
Normal file
8
backend/src/main/resources/application.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
# Database connection
|
||||
spring.datasource.url=jdbc:postgresql://localhost:5432/halflink
|
||||
spring.datasource.username=springchatuser
|
||||
spring.datasource.password=abcdef
|
||||
|
||||
# JPA/Hibernate settings
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.show-sql=true
|
||||
11
backend/src/main/resources/sandbox.http
Normal file
11
backend/src/main/resources/sandbox.http
Normal file
@@ -0,0 +1,11 @@
|
||||
POST http://localhost:8080/sl
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"url": "https://docs.spring.io/spring-security/reference/servlet/authentication/index.html",
|
||||
"title": "Spring Security Servlet Authentication"
|
||||
}
|
||||
|
||||
###
|
||||
|
||||
DELETE http://localhost:8080/sl/a0232bf3-245d-4515-8a8b-c10031d21766
|
||||
Reference in New Issue
Block a user