Initialise Spring API with ShortLink endpoints

This commit is contained in:
2025-12-22 18:43:19 +00:00
commit 4107d7a248
9 changed files with 236 additions and 0 deletions

View 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);
}
}

View File

@@ -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);
}
}

View 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; }
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View 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

View 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