Giter VIP home page Giter VIP logo

spring-a-gram's Introduction

Spring-a-Gram is a demonstration of the Spring stack used to upload and view pictures.

Spring Data REST makes it incredibly simple to define and export data store entities. What does this mean? You declare the POJOs that are stored in your database. In this case, we are using a JPA, in-memory data store. (Spring Data REST supports other data stores as well). You then define a related repository interface. Spring Data REST takes it from there to create a hypermedia-driven, RESTful interface using Spring MVC that lets you create, read, update, and delete data.

This sample application demonstrations how declaring a backend aimed at storing image data can make it as simple as possible to upload pictures and then turn around and display them on a website. This opens the door to other front ends, like an iOS or Android app.

If you want to run it right now, you need:

To download and run:

  1. git clone [email protected]:gregturn/spring-a-gram.git to grab a local copy (or clone your own fork).

  2. bower install to pull down javascript libraries. If you get prompted about jQuery, accept the version specified in bower.json

  3. mvn clean spring-boot:run

Note
To deploy a copy to PWS, you need a Java 8 build pack. Execute cf push spring-a-gram -p target/spring-a-gram-0.1.0.jar -b https://github.com/spring-io/java-buildpack.git and you’ll be set.

This should get the app started courtesy of Spring Boot. Now you can traverse the app from different view points.

  • From the command line, interrogate the API with curl localhost:8080/api. Navigate to the other links.

  • From the desktop, visit http://localhost:8080 to see the Desktop version of the web experience.

  • From a mobile device, visit http://localhost:8080 and see a different flow, optimized for the smaller real estate.

Let’s explore.

Defining an item to store

src/main/java/com/greglturnquist/springagram/Item.java

package com.greglturnquist.springagram;

/* some import statements */

@Entity
public class Item {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private long id;

	private String name;

	@Lob
	private String image;

	@ManyToOne
	private Gallery gallery;
	...

The core piece of this app are the Items. Each one contains an auto-generated id, a name, a raw image (stored in the format of a String) and an optional Gallery.

Note
Java strings are wide and generally unicode based. To store the raw data of a picture in the database, it has been tagged with @Lob, a JPA annotation used to signal this a Large Object.

Creating a place to gather items

We declared up above that Items can be put in Galleries. This gives us the opportunity to define a relationship and see to manage it through the RESTful endpoints later on.

src/main/java/com/greglturnquist/springagram/Gallery.java

package com.greglturnquist.springagram;

/* import statements */

@Entity
public class Gallery {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private long id;

	private String description;

	@OneToMany(mappedBy = "gallery")
	private List<Item> items;
	...

A Gallery has an id, a description, and can contain zero or more Items.

Create the simplest repository interface possible

src/main/java/com/greglturnquist/springagram/ItemRepository.java

package com.greglturnquist.springagram;

import java.util.List;

import org.springframework.data.repository.CrudRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

@RepositoryRestResource()
public interface ItemRepository extends CrudRepository<Item, Long> {

	List<Item> findByGalleryIsNull();

}

ItemRepository has one custom finder method, and that’s to get a listing of items that are NOT assigned to a gallery.

src/main/java/com/greglturnquist/springagram/GalleryRepository.java

package com.greglturnquist.springagram;

import org.springframework.data.repository.CrudRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

@RepositoryRestResource
public interface GalleryRepository extends CrudRepository<Gallery, Long> {
}

All of the Spring Data projects are based on this similar concept: define an interface that extends either CrudRepository or PagingAndSortingRepository and then let Spring Data create a proxied concrete implementation. You get a handful of built in operations. You can add custom queries, but we aren’t doing that right now.

Both of these interfaces have an extra annotation: RepositoryRestResource. This annotation provides the means to change parts of the URLs and hypermedia, but we aren’t using that here.

Note
If you notice the end of the declaration where it says <Item, Long> and <Gallery, Long>, that indicates the entity type and the type of its keys.

Spinning up a RESTful server app

One last piece remains. We need a runnable app. By default, Spring Data REST serves up our hypermedia interface at /. To alter it, we need to subclass a piece of Spring Data REST.

@Configuration
public class CustomizedRestMvcConfiguration extends RepositoryRestMvcConfiguration {

	@Override
	public RepositoryRestConfiguration config() {
		RepositoryRestConfiguration config = super.config();
		config.setBaseUri(URI.create("/api"));
		return config;
	}
}

This class sets the baseUri to /api. Why would you want to do this? So when you point your browser at http://localhost:8080, you see the web page not the JSON served up by the hypermedia.

src/main/java/com/greglturnquist/springagram/Application.java

package com.greglturnquist.springagram;

/* import statements */

@Configuration
@EnableJpaRepositories
@Import(CustomizedRestMvcConfiguration.class)
@EnableAutoConfiguration
@ComponentScan
public class Application {

	public static void main(String[] args) throws IOException {
		SpringApplication.run(Application.class, args);
	}
}

This is mostly boilerplate. It contains key annotations to declare and launch an application.

  • @Configuration means this class is the source of beans for a Spring app

  • @EnableJpaRepositories turns on the ability to scan and detect JPA entities and repository interfaces

  • @Import(CustomizedRestMvcConfiguration.class) pulls in a handful of beans needed to launch Spring Data REST, which is really a specialized Spring MVC app

  • @EnableAutoConfiguration tells Spring Boot to autoconfigure as much as possible

  • @ComponentScan tells Spring to look for any other classes in the same package that are configurable, such as @Component’s, @Service’s, and @Controller’s

This code, by itself, it enough to spin up a RESTful, hypermedia based app. There is no visual element here. You only have access to tools like curl or whatever REST client you wish to use. But you can perform all the CRUD operations you want.

At the root, you can see what links are available.

$ curl localhost:8080/api
{
  "_links" : {
    "items" : {
      "href" : "http://localhost:8080/api/items"
    },
    "galleries" : {
      "href" : "http://localhost:8080/api/galleries"
    }
  }
}
  • /api/items is where individual items are stored.

  • /api/galleries is where the galleries are stored.

$ curl localhost:8080/api/items
{
  "_links" : {
    "search" : {
      "href" : "http://localhost:8080/api/items/search"
    }
  }
}

Here you can see there are no entries yet. You can go on and explore the other links to get a feel for things.

Building a rich front end

To dial up the visual appeal and show easy Spring Data REST makes it to build your own picture sharing service, I added a web page.

It’s pretty simple. It contains a form where you can pick a picture and submit it for upload. Following that is a table to display a thumbnail-sized version of each picture.

  • This app is using webjars to fetch a copy of jQuery

In encourage you to skim through all the code to see how it readily demonstrates the power and simplicity of having a complete, RESTful service.

spring-a-gram's People

Contributors

gregturn avatar royclarkson avatar unscriptable avatar briancavalier avatar

Watchers

Daniel Aquino avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.