diff --git a/reponses.md b/reponses.md
new file mode 100644
index 0000000000000000000000000000000000000000..4b2ada3e16ff8375c0ca987a92bdbe630ef2f8ed
--- /dev/null
+++ b/reponses.md
@@ -0,0 +1,11 @@
+1d) créer un ingrédient :
+curl -i --noproxy localhost -H "Con" --data-raw '{"name":"saucisse"}' localhost:8080/api/v1/ingredients
+
+récupérer la liste des ingrédients :
+curl -i --noproxy localhost localhost:8080/api/v1/ingredients
+
+récupérer l'ingrédient 13 par exemple :
+curl -i --noproxy localhost localhost:8080/api/v1/ingredients/13
+
+détruire l'ingrédient 13 :
+curl -i --noproxy localhost -X "DELETE" localhost:8080/api/v1/ingredients/13
\ No newline at end of file
diff --git a/src/main/java/fr/ulille/iut/pizzaland/ApiV1.java b/src/main/java/fr/ulille/iut/pizzaland/ApiV1.java
index b565c8399d5213fc5b2335568b0224cea580b1e5..e275d31091934e57e75f2d6003353c4a1e0d702c 100644
--- a/src/main/java/fr/ulille/iut/pizzaland/ApiV1.java
+++ b/src/main/java/fr/ulille/iut/pizzaland/ApiV1.java
@@ -1,16 +1,47 @@
 package fr.ulille.iut.pizzaland;
 
+import java.io.FileReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.json.bind.Jsonb;
+import javax.json.bind.JsonbBuilder;
+import javax.ws.rs.ApplicationPath;
+
 import org.glassfish.jersey.server.ResourceConfig;
 
-import java.util.logging.Logger;
+import fr.ulille.iut.pizzaland.beans.Ingredient;
+import fr.ulille.iut.pizzaland.dao.IngredientDao;
+import fr.ulille.iut.pizzaland.dao.PizzaDao;
 
-import javax.ws.rs.ApplicationPath;
 
 @ApplicationPath("api/v1/")
 public class ApiV1 extends ResourceConfig {
-    private static final Logger LOGGER = Logger.getLogger(ApiV1.class.getName());
+	public ApiV1() {
+		packages("fr.ulille.iut.pizzaland");
+
+		String environment = System.getenv("PIZZAENV");
+
+		if (environment != null && environment.equals("withdb")) {
+			Jsonb jsonb = JsonbBuilder.create();
+			try {
+				FileReader reader = new FileReader(
+						getClass().getClassLoader().getResource("ingredients.json").getFile());
+				List<Ingredient> ingredients = JsonbBuilder.create().fromJson(reader, new ArrayList<Ingredient>() {
+				}.getClass().getGenericSuperclass());
 
-    public ApiV1() {
-        packages("fr.ulille.iut.pizzaland");
-    }
+				IngredientDao ingredientDao = BDDFactory.buildDao(IngredientDao.class);
+				ingredientDao.dropTable();
+				ingredientDao.createTable();
+				PizzaDao pizzaDao = BDDFactory.buildDao(PizzaDao.class);
+				pizzaDao.dropTable();
+				pizzaDao.createTable();
+				for (Ingredient ingredient : ingredients) {
+					ingredientDao.insert(ingredient.getName());
+				}
+			} catch (Exception ex) {
+				throw new IllegalStateException(ex);
+			}
+		}
+	}
 }
diff --git a/src/main/java/fr/ulille/iut/pizzaland/beans/Ingredient.java b/src/main/java/fr/ulille/iut/pizzaland/beans/Ingredient.java
new file mode 100644
index 0000000000000000000000000000000000000000..eb9b4d8bd55b86eb6ca7e7b2d0b25827fdc4834c
--- /dev/null
+++ b/src/main/java/fr/ulille/iut/pizzaland/beans/Ingredient.java
@@ -0,0 +1,87 @@
+package fr.ulille.iut.pizzaland.beans;
+
+import fr.ulille.iut.pizzaland.dto.IngredientCreateDto;
+import fr.ulille.iut.pizzaland.dto.IngredientDto;
+
+public class Ingredient {
+	private long id;
+	private String name;
+
+	public Ingredient() {
+	}
+
+	public Ingredient(long id, String name) {
+		this.id = id;
+		this.name = name;
+	}
+
+	public void setId(long id) {
+		this.id = id;
+	}
+
+	public long getId() {
+		return id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public static IngredientDto toDto(Ingredient i) {
+		IngredientDto dto = new IngredientDto();
+		dto.setId(i.getId());
+		dto.setName(i.getName());
+
+		return dto;
+	}
+
+	public static Ingredient fromDto(IngredientDto dto) {
+		Ingredient ingredient = new Ingredient();
+		ingredient.setId(dto.getId());
+		ingredient.setName(dto.getName());
+
+		return ingredient;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Ingredient other = (Ingredient) obj;
+		if (id != other.id)
+			return false;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "Ingredient [id=" + id + ", name=" + name + "]";
+	}
+
+	public static IngredientCreateDto toCreateDto(Ingredient ingredient) {
+		IngredientCreateDto dto = new IngredientCreateDto();
+		dto.setName(ingredient.getName());
+
+		return dto;
+	}
+
+	public static Ingredient fromIngredientCreateDto(IngredientCreateDto dto) {
+		Ingredient ingredient = new Ingredient();
+		ingredient.setName(dto.getName());
+
+		return ingredient;
+	}
+}
diff --git a/src/main/java/fr/ulille/iut/pizzaland/beans/Pizza.java b/src/main/java/fr/ulille/iut/pizzaland/beans/Pizza.java
new file mode 100644
index 0000000000000000000000000000000000000000..08979369ed3014596003035581a967d5ca764a91
--- /dev/null
+++ b/src/main/java/fr/ulille/iut/pizzaland/beans/Pizza.java
@@ -0,0 +1,105 @@
+package fr.ulille.iut.pizzaland.beans;
+
+import java.util.List;
+
+import fr.ulille.iut.pizzaland.dto.PizzaCreateDto;
+import fr.ulille.iut.pizzaland.dto.PizzaDto;
+
+public class Pizza {
+	private List<Ingredient> ingredients;
+	private long id;
+	private String name;
+
+	public Pizza() {
+	}
+
+	public Pizza(List<Ingredient> ingredients, long id, String name) {
+		this.ingredients = ingredients;
+		this.id = id;
+		this.name = name;
+	}
+
+	public void setIngredients(List<Ingredient> ingredients) {
+		this.ingredients = ingredients;
+	}
+
+	public List<Ingredient> getIngredients() {
+		return ingredients;
+	}
+
+	public void setId(long id) {
+		this.id = id;
+	}
+
+	public long getId() {
+		return id;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public static PizzaDto toDto(Pizza p) {
+		PizzaDto dto = new PizzaDto();
+		dto.setIngredients(p.getIngredients());
+		dto.setId(p.getId());
+		dto.setName(p.getName());
+
+		return dto;
+	}
+
+	public static Pizza fromDto(PizzaDto dto) {
+		Pizza pizza = new Pizza();
+		pizza.setIngredients(dto.getIngredients());
+		pizza.setId(dto.getId());
+		pizza.setName(dto.getName());
+
+		return pizza;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Pizza other = (Pizza) obj;
+		if (ingredients != other.ingredients)
+			return false;
+		if (id != other.id)
+			return false;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "Pizza [id = " + id + ", name = " + name + ", ingredients = " + ingredients + "]";
+	}
+
+	public static PizzaCreateDto toCreateDto(Pizza pizza) {
+		PizzaCreateDto dto = new PizzaCreateDto();
+		dto.setIngredients(pizza.getIngredients());
+		dto.setName(pizza.getName());
+		
+		return dto;
+	}
+
+	public static Pizza fromPizzaCreateDto(PizzaCreateDto dto) {
+		Pizza pizza = new Pizza();
+		pizza.setIngredients(dto.getIngredients());
+		pizza.setName(dto.getName());
+
+		return pizza;
+	}
+}
diff --git a/src/main/java/fr/ulille/iut/pizzaland/dao/IngredientDao.java b/src/main/java/fr/ulille/iut/pizzaland/dao/IngredientDao.java
new file mode 100644
index 0000000000000000000000000000000000000000..a4f950d0138b19248becc12e4524a3e660043cb0
--- /dev/null
+++ b/src/main/java/fr/ulille/iut/pizzaland/dao/IngredientDao.java
@@ -0,0 +1,43 @@
+package fr.ulille.iut.pizzaland.dao;
+
+import java.util.List;
+
+import org.jdbi.v3.sqlobject.config.RegisterBeanMapper;
+import org.jdbi.v3.sqlobject.statement.GetGeneratedKeys;
+import org.jdbi.v3.sqlobject.statement.SqlQuery;
+import org.jdbi.v3.sqlobject.statement.SqlUpdate;
+
+import fr.ulille.iut.pizzaland.beans.Ingredient;
+
+public interface IngredientDao {
+	
+	@SqlUpdate("CREATE TABLE IF NOT EXISTS ingredients (id INTEGER PRIMARY KEY, name VARCHAR UNIQUE NOT NULL)")
+	void createTable();
+
+	@SqlUpdate("DROP TABLE IF EXISTS ingredients")
+	void dropTable();
+
+	@SqlUpdate("INSERT INTO ingredients (name) VALUES (:name)")
+	@GetGeneratedKeys
+	long insert(String name);
+
+	@SqlQuery("SELECT * FROM ingredients")
+	@RegisterBeanMapper(Ingredient.class)
+	List<Ingredient> getAll();
+	
+	@SqlQuery("SELECT id, name FROM pizzasAndIngredients as pai, ingredients as i WHERE pai.ingredient = i.id AND pai.pizza = :pizzaId")
+	@RegisterBeanMapper(Ingredient.class)
+	List<Ingredient> getAllIngredientsOfPizza(long pizzaId);
+
+	@SqlQuery("SELECT * FROM ingredients WHERE id = :id")
+	@RegisterBeanMapper(Ingredient.class)
+	Ingredient findById(long id);
+
+	@SqlQuery("SELECT * FROM ingredients WHERE name = :name")
+	@RegisterBeanMapper(Ingredient.class)
+	Ingredient findByName(String name);
+	
+	@SqlUpdate("DELETE FROM ingredients WHERE id = :id")
+	void remove(long id);
+
+}
diff --git a/src/main/java/fr/ulille/iut/pizzaland/dao/PizzaDao.java b/src/main/java/fr/ulille/iut/pizzaland/dao/PizzaDao.java
new file mode 100644
index 0000000000000000000000000000000000000000..dc447e81f8dcbffa67bacd14d6ad6f19c591480c
--- /dev/null
+++ b/src/main/java/fr/ulille/iut/pizzaland/dao/PizzaDao.java
@@ -0,0 +1,90 @@
+package fr.ulille.iut.pizzaland.dao;
+
+import java.util.List;
+
+import org.jdbi.v3.sqlobject.config.RegisterBeanMapper;
+import org.jdbi.v3.sqlobject.statement.GetGeneratedKeys;
+import org.jdbi.v3.sqlobject.statement.SqlQuery;
+import org.jdbi.v3.sqlobject.statement.SqlUpdate;
+
+import fr.ulille.iut.pizzaland.BDDFactory;
+import fr.ulille.iut.pizzaland.beans.Ingredient;
+import fr.ulille.iut.pizzaland.beans.Pizza;
+
+public interface PizzaDao {
+	static IngredientDao ingredientDao = BDDFactory.buildDao(IngredientDao.class);
+
+	@SqlUpdate("CREATE TABLE IF NOT EXISTS pizzas (id INTEGER PRIMARY KEY, name VARCHAR)")
+	void createPizzaTable();
+
+	@SqlUpdate("CREATE TABLE IF NOT EXISTS pizzasAndIngredients (pizza INTEGER,"
+			+ " ingredient INTEGER,"
+			+ " PRIMARY KEY(pizza, ingredient),"
+			+ " FOREIGN KEY pizza REFERENCES pizzas(id),"
+			+ " FOREIGN KEY ingredient REFERENCES ingredients(id))")
+	void createAssociationTable();
+
+	default void createTable() {
+		createPizzaTable();
+		createAssociationTable();
+	}
+	
+	@SqlQuery("SELECT ingredient FROM pizzasAndIngredients WHERE pizza = :pizzaId")
+	long getId(long pizzaId);
+
+	@SqlUpdate("DROP TABLE IF EXISTS pizzas")
+	void dropTable();
+
+	@SqlUpdate("INSERT INTO pizzas (name) VALUES (:name)")
+	@GetGeneratedKeys
+	long insertPizza(String name);
+	
+	@SqlUpdate("INSERT INTO pizzasAndIngredients VALUES (:pizza, :ingredient")
+	public void associatePizzaWithIngredient(long pizza, long ingredient);
+	
+	public default long insert(String name, List<Ingredient> ingredients) {
+		long pizzaId = insertPizza(name);
+		
+		for(Ingredient ingredient : ingredients)
+			associatePizzaWithIngredient(pizzaId, ingredient.getId());
+		return pizzaId;
+	}
+
+	@SqlQuery("SELECT * FROM pizzas")
+	@RegisterBeanMapper(Pizza.class)
+	List<Pizza> getAll();
+
+	default List<Pizza> getAllPizzas() {
+		List<Pizza> pizzas = getAll();
+
+		for (Pizza pizza : pizzas)
+			pizza.setIngredients(ingredientDao.getAllIngredientsOfPizza(getId(pizza.getId())));
+
+		return pizzas;
+	}
+
+	@SqlQuery("SELECT * FROM pizzas WHERE id = :id")
+	@RegisterBeanMapper(Pizza.class)
+	Pizza findById(long id);
+
+	default Pizza getPizzaById(long id) {
+		Pizza pizza = findById(id);
+		pizza.setIngredients(ingredientDao.getAllIngredientsOfPizza(id));
+		return pizza;
+	}
+
+	@SqlQuery("SELECT * FROM pizzas WHERE name = :name")
+	@RegisterBeanMapper(Pizza.class)
+	Pizza findByName(String name);
+
+	@SqlUpdate("DELETE FROM pizzasAndIngredient WHERE pizza = :id")
+	void removePAI(long id);
+
+	@SqlUpdate("DELETE FROM pizzas WHERE id = :id")
+	void removePizza(long id);
+
+	default void remove(long id) {
+		removePAI(id);
+		removePizza(id);
+	}
+}
diff --git a/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientCreateDto.java b/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientCreateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..9c979192cd5f2d25a95e258c858f21612550bf3e
--- /dev/null
+++ b/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientCreateDto.java
@@ -0,0 +1,16 @@
+package fr.ulille.iut.pizzaland.dto;
+
+public class IngredientCreateDto {
+	private String name;
+
+	public IngredientCreateDto() {
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+}
diff --git a/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientDto.java b/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientDto.java
index 1a9360bf01fa2544b241a017cfa0c056dada02e2..7bc8680635e0bc244613ac746233404d988dc0e1 100644
--- a/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientDto.java
+++ b/src/main/java/fr/ulille/iut/pizzaland/dto/IngredientDto.java
@@ -1,8 +1,25 @@
 package fr.ulille.iut.pizzaland.dto;
 
 public class IngredientDto {
+	private long id;
+	private String name;
 
-    public IngredientDto() {
-        
-    }
+	public IngredientDto() {
+	}
+
+	public long getId() {
+		return id;
+	}
+
+	public void setId(long id) {
+		this.id = id;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
 }
diff --git a/src/main/java/fr/ulille/iut/pizzaland/dto/PizzaCreateDto.java b/src/main/java/fr/ulille/iut/pizzaland/dto/PizzaCreateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..42b97b827f834605c4498dc4d0940c218ce4cd72
--- /dev/null
+++ b/src/main/java/fr/ulille/iut/pizzaland/dto/PizzaCreateDto.java
@@ -0,0 +1,29 @@
+package fr.ulille.iut.pizzaland.dto;
+
+import java.util.List;
+
+import fr.ulille.iut.pizzaland.beans.Ingredient;
+
+public class PizzaCreateDto {
+	private List<Ingredient> ingredients;
+	private String name;
+
+	public PizzaCreateDto() {
+	}
+
+	public void setIngredients(List<Ingredient> ingredients) {
+		this.ingredients = ingredients;
+	}
+
+	public List<Ingredient> getIngredients() {
+		return ingredients;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public String getName() {
+		return name;
+	}
+}
diff --git a/src/main/java/fr/ulille/iut/pizzaland/dto/PizzaDto.java b/src/main/java/fr/ulille/iut/pizzaland/dto/PizzaDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..2375d378334fa733c29b12e5bd785f811268ea44
--- /dev/null
+++ b/src/main/java/fr/ulille/iut/pizzaland/dto/PizzaDto.java
@@ -0,0 +1,38 @@
+package fr.ulille.iut.pizzaland.dto;
+
+import java.util.List;
+
+import fr.ulille.iut.pizzaland.beans.Ingredient;
+
+public class PizzaDto {
+	private List<Ingredient> ingredients;
+	private long id;
+	private String name;
+	
+	public PizzaDto() {
+	}
+
+	public List<Ingredient> getIngredients() {
+		return ingredients;
+	}
+
+	public void setIngredients(List<Ingredient> ingredients) {
+		this.ingredients = ingredients;
+	}
+
+	public long getId() {
+		return id;
+	}
+	
+	public void setId(long id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+}
diff --git a/src/main/java/fr/ulille/iut/pizzaland/resources/IngredientResource.java b/src/main/java/fr/ulille/iut/pizzaland/resources/IngredientResource.java
index bc19082daf4dd4cd778b956d9607e2f259a94cd1..78321d49406b8dc6937505205fa17d412273dea7 100644
--- a/src/main/java/fr/ulille/iut/pizzaland/resources/IngredientResource.java
+++ b/src/main/java/fr/ulille/iut/pizzaland/resources/IngredientResource.java
@@ -2,31 +2,101 @@ package fr.ulille.iut.pizzaland.resources;
 
 import java.net.URI;
 import java.util.List;
-import java.util.ArrayList;
 import java.util.logging.Logger;
+import java.util.stream.Collectors;
 
+import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
+import javax.ws.rs.POST;
 import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 
+import fr.ulille.iut.pizzaland.BDDFactory;
+import fr.ulille.iut.pizzaland.beans.Ingredient;
+import fr.ulille.iut.pizzaland.dao.IngredientDao;
+import fr.ulille.iut.pizzaland.dto.IngredientCreateDto;
 import fr.ulille.iut.pizzaland.dto.IngredientDto;
 
 @Path("/ingredients")
 public class IngredientResource {
-    private static final Logger LOGGER = Logger.getLogger(IngredientResource.class.getName());
+	private static final Logger LOGGER = Logger.getLogger(IngredientResource.class.getName());
+	private IngredientDao ingredients;
 
-    @Context
-    public UriInfo uriInfo;
+	@Context
+	public UriInfo uriInfo;
 
-    public IngredientResource() {
-    }
+	public IngredientResource() {
+		ingredients = BDDFactory.buildDao(IngredientDao.class);
+		ingredients.createTable();
+	}
 
-    @GET
-    public List<IngredientDto> getAll() {
-        LOGGER.info("IngredientResource:getAll");
+	@GET
+	public List<IngredientDto> getAll() {
+		LOGGER.info("IngredientResource:getAll");
 
-	return null;
-    }
+		List<IngredientDto> l = ingredients.getAll().stream().map(Ingredient::toDto).collect(Collectors.toList());
+		return l;
+	}
+
+	@GET
+	@Path("{id}")
+	public IngredientDto getOneIngredient(@PathParam("id") long id) {
+		LOGGER.info("getOneIngredient(" + id + ")");
+		try {
+			Ingredient ingredient = ingredients.findById(id);
+			return Ingredient.toDto(ingredient);
+		} catch (Exception e) {
+			// Cette exception générera une réponse avec une erreur 404
+			throw new WebApplicationException(Response.Status.NOT_FOUND);
+		}
+	}
+
+	@POST
+	public Response createIngredient(IngredientCreateDto ingredientCreateDto) {
+		Ingredient existing = ingredients.findByName(ingredientCreateDto.getName());
+		if (existing != null) {
+			throw new WebApplicationException(Response.Status.CONFLICT);
+		}
+
+		try {
+			Ingredient ingredient = Ingredient.fromIngredientCreateDto(ingredientCreateDto);
+			long id = ingredients.insert(ingredient.getName());
+			ingredient.setId(id);
+			IngredientDto ingredientDto = Ingredient.toDto(ingredient);
+
+			URI uri = uriInfo.getAbsolutePathBuilder().path("" + id).build();
+
+			return Response.created(uri).entity(ingredientDto).build();
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new WebApplicationException(Response.Status.NOT_ACCEPTABLE);
+		}
+	}
+
+	@DELETE
+	@Path("{id}")
+	public Response deleteIngredient(@PathParam("id") long id) {
+		if (ingredients.findById(id) == null) {
+			throw new WebApplicationException(Response.Status.NOT_FOUND);
+		}
+
+		ingredients.remove(id);
+
+		return Response.status(Response.Status.ACCEPTED).build();
+	}
+
+	@GET
+	@Path("{id}/name")
+	public String getIngredientName(@PathParam("id") long id) {
+		Ingredient ingredient = ingredients.findById(id);
+		if (ingredient == null) {
+			throw new WebApplicationException(Response.Status.NOT_FOUND);
+		}
+
+		return ingredient.getName();
+	}
 }
diff --git a/src/main/java/fr/ulille/iut/pizzaland/resources/PizzaResource.java b/src/main/java/fr/ulille/iut/pizzaland/resources/PizzaResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..d5d2c42432864eaf2d22121b501fc4821153410f
--- /dev/null
+++ b/src/main/java/fr/ulille/iut/pizzaland/resources/PizzaResource.java
@@ -0,0 +1,102 @@
+package fr.ulille.iut.pizzaland.resources;
+
+import java.net.URI;
+import java.util.List;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import fr.ulille.iut.pizzaland.BDDFactory;
+import fr.ulille.iut.pizzaland.beans.Pizza;
+import fr.ulille.iut.pizzaland.dao.PizzaDao;
+import fr.ulille.iut.pizzaland.dto.PizzaCreateDto;
+import fr.ulille.iut.pizzaland.dto.PizzaDto;
+
+@Path("/pizzas")
+public class PizzaResource {
+	private static final Logger LOGGER = Logger.getLogger(PizzaResource.class.getName());
+	private PizzaDao pizzas;
+
+	@Context
+	public UriInfo uriInfo;
+
+	public PizzaResource() {
+		pizzas = BDDFactory.buildDao(PizzaDao.class);
+		pizzas.createTable();
+	}
+
+	@GET
+	public List<PizzaDto> getAll() {
+		LOGGER.info("PizzaResource:getAll");
+
+		List<PizzaDto> l = pizzas.getAll().stream().map(Pizza::toDto).collect(Collectors.toList());
+		return l;
+	}
+
+	@GET
+	@Path("{id}")
+	public PizzaDto getOnePizza(@PathParam("id") long id) {
+		LOGGER.info("getOnePizza(" + id + ")");
+		try {
+			Pizza pizza = pizzas.findById(id);
+			return Pizza.toDto(pizza);
+		} catch (Exception e) {
+			// Cette exception générera une réponse avec une erreur 404
+			throw new WebApplicationException(Response.Status.NOT_FOUND);
+		}
+	}
+
+	@POST
+	public Response createPizza(PizzaCreateDto pizzaCreateDto) {
+		Pizza existing = pizzas.findByName(pizzaCreateDto.getName());
+		if (existing != null) {
+			throw new WebApplicationException(Response.Status.CONFLICT);
+		}
+
+		try {
+			Pizza pizza = Pizza.fromPizzaCreateDto(pizzaCreateDto);
+			long id = pizzas.insert(pizza.getName(), pizza.getIngredients());
+			pizza.setId(id);
+			PizzaDto pizzaDto = Pizza.toDto(pizza);
+
+			URI uri = uriInfo.getAbsolutePathBuilder().path("" + id).build();
+
+			return Response.created(uri).entity(pizzaDto).build();
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new WebApplicationException(Response.Status.NOT_ACCEPTABLE);
+		}
+	}
+
+	@DELETE
+	@Path("{id}")
+	public Response deleteIngredient(@PathParam("id") long id) {
+		if (pizzas.findById(id) == null) {
+			throw new WebApplicationException(Response.Status.NOT_FOUND);
+		}
+
+		pizzas.remove(id);
+
+		return Response.status(Response.Status.ACCEPTED).build();
+	}
+
+	@GET
+	@Path("{id}/name")
+	public String getPizzaName(@PathParam("id") long id) {
+		Pizza pizza = pizzas.findById(id);
+		if (pizza == null) {
+			throw new WebApplicationException(Response.Status.NOT_FOUND);
+		}
+
+		return pizza.getName();
+	}
+}
diff --git a/src/test/java/fr/ulille/iut/pizzaland/IngredientResourceTest.java b/src/test/java/fr/ulille/iut/pizzaland/IngredientResourceTest.java
index 2c8b1be3f265046d4d3557185aac26b7704ec1ac..7643f1175a2f326f3d9e74a2fa8a298e542a9bad 100644
--- a/src/test/java/fr/ulille/iut/pizzaland/IngredientResourceTest.java
+++ b/src/test/java/fr/ulille/iut/pizzaland/IngredientResourceTest.java
@@ -1,23 +1,24 @@
 package fr.ulille.iut.pizzaland;
 
-import fr.ulille.iut.pizzaland.ApiV1;
-import fr.ulille.iut.pizzaland.dto.IngredientDto;
+import static org.junit.Assert.assertEquals;
 
-import org.glassfish.jersey.test.JerseyTest;
-import org.glassfish.jersey.test.TestProperties;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
+import java.util.List;
+import java.util.logging.Logger;
 
 import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.GenericType;
 import javax.ws.rs.core.Application;
+import javax.ws.rs.core.GenericType;
 import javax.ws.rs.core.Response;
 
-import static org.junit.Assert.assertEquals;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 
-import java.util.List;
-import java.util.logging.Logger;
+import fr.ulille.iut.pizzaland.beans.Ingredient;
+import fr.ulille.iut.pizzaland.dao.IngredientDao;
+import fr.ulille.iut.pizzaland.dto.IngredientCreateDto;
+import fr.ulille.iut.pizzaland.dto.IngredientDto;
 
 /*
  * JerseyTest facilite l'écriture des tests en donnant accès aux
@@ -25,45 +26,151 @@ import java.util.logging.Logger;
  * la méthode configure() permet de démarrer la ressource à tester
  */
 public class IngredientResourceTest extends JerseyTest {
-    private static final Logger LOGGER = Logger.getLogger(IngredientResourceTest.class.getName());
-    
-    @Override
-    protected Application configure() {
-       return new ApiV1();
-    }
-
-    // Les méthodes setEnvUp() et tearEnvDown() serviront à terme à initialiser la base de données
-    // et les DAO
-    
-    // https://stackoverflow.com/questions/25906976/jerseytest-and-junit-throws-nullpointerexception
-    @Before
-    public void setEnvUp() {
-	
-    }
-
-    @After
-    public void tearEnvDown() throws Exception {
-
-    }
-
-    @Test
-    public void testGetEmptyList() {
-	// La méthode target() permet de préparer une requête sur une URI.
-	// La classe Response permet de traiter la réponse HTTP reçue.
-        Response response = target("/ingredients").request().get();
-
-	// On vérifie le code de la réponse (200 = OK)
-        assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
-
-		  
-	// On vérifie la valeur retournée (liste vide)
-	// L'entité (readEntity() correspond au corps de la réponse HTTP.
-	// La classe javax.ws.rs.core.GenericType<T> permet de définir le type
-	// de la réponse lue quand on a un type complexe (typiquement une liste).
-	List<IngredientDto> ingredients;
-        ingredients = response.readEntity(new GenericType<List<IngredientDto>>(){});
-
-        assertEquals(0, ingredients.size());
-
-    }
+	private static final Logger LOGGER = Logger.getLogger(IngredientResourceTest.class.getName());
+	private IngredientDao dao;
+
+	@Override
+	protected Application configure() {
+		BDDFactory.setJdbiForTests();
+		return new ApiV1();
+	}
+
+	// Les méthodes setEnvUp() et tearEnvDown() serviront à terme à initialiser la
+	// base de données
+	// et les DAO
+
+	// https://stackoverflow.com/questions/25906976/jerseytest-and-junit-throws-nullpointerexception
+	@Before
+	public void setEnvUp() {
+		dao = BDDFactory.buildDao(IngredientDao.class);
+		dao.createTable();
+	}
+
+	@After
+	public void tearEnvDown() throws Exception {
+		dao.dropTable();
+	}
+
+	@Test
+	public void testGetEmptyList() {
+		// La méthode target() permet de préparer une requête sur une URI.
+		// La classe Response permet de traiter la réponse HTTP reçue.
+		Response response = target("/ingredients").request().get();
+
+		// On vérifie le code de la réponse (200 = OK)
+		assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+		// On vérifie la valeur retournée (liste vide)
+		// L'entité (readEntity() correspond au corps de la réponse HTTP.
+		// La classe javax.ws.rs.core.GenericType<T> permet de définir le type
+		// de la réponse lue quand on a un type complexe (typiquement une liste).
+		List<IngredientDto> ingredients;
+		ingredients = response.readEntity(new GenericType<List<IngredientDto>>() {
+		});
+
+		assertEquals(0, ingredients.size());
+	}
+
+	@Test
+	public void testGetExistingIngredient() {
+		Ingredient ingredient = new Ingredient();
+		ingredient.setName("Chorizo");
+
+		long id = dao.insert(ingredient.getName());
+		ingredient.setId(id);
+
+		Response response = target("/ingredients/" + id).request().get();
+
+		assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+		Ingredient result = Ingredient.fromDto(response.readEntity(IngredientDto.class));
+		assertEquals(ingredient, result);
+	}
+
+	@Test
+	public void testGetNotExistingPizza() {
+		Response response = target("/pizzas/125").request().get();
+		assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus());
+	}
+
+	@Test
+	public void testCreateIngredient() {
+		IngredientCreateDto ingredientCreateDto = new IngredientCreateDto();
+		ingredientCreateDto.setName("Chorizo");
+
+		Response response = target("/ingredients").request().post(Entity.json(ingredientCreateDto));
+
+		// On vérifie le code de status à 201
+		assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+
+		IngredientDto returnedEntity = response.readEntity(IngredientDto.class);
+
+		// On vérifie que le champ d'entête Location correspond à
+		// l'URI de la nouvelle entité
+		assertEquals(target("/ingredients/" + returnedEntity.getId()).getUri(), response.getLocation());
+
+		// On vérifie que le nom correspond
+		assertEquals(returnedEntity.getName(), ingredientCreateDto.getName());
+	}
+
+	@Test
+	public void testCreateSameIngredient() {
+		IngredientCreateDto ingredientCreateDto = new IngredientCreateDto();
+		ingredientCreateDto.setName("Chorizo");
+		dao.insert(ingredientCreateDto.getName());
+
+		Response response = target("/ingredients").request().post(Entity.json(ingredientCreateDto));
+
+		assertEquals(Response.Status.CONFLICT.getStatusCode(), response.getStatus());
+	}
+
+	@Test
+	public void testCreateIngredientWithoutName() {
+		IngredientCreateDto ingredientCreateDto = new IngredientCreateDto();
+
+		Response response = target("/ingredients").request().post(Entity.json(ingredientCreateDto));
+
+		assertEquals(Response.Status.NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+	}
+
+	@Test
+	public void testDeleteExistingIngredient() {
+		Ingredient ingredient = new Ingredient();
+		ingredient.setName("Chorizo");
+		long id = dao.insert(ingredient.getName());
+		ingredient.setId(id);
+
+		Response response = target("/ingredients/" + id).request().delete();
+
+		assertEquals(Response.Status.ACCEPTED.getStatusCode(), response.getStatus());
+
+		Ingredient result = dao.findById(id);
+		assertEquals(result, null);
+	}
+
+	@Test
+	public void testDeleteNotExistingIngredient() {
+		Response response = target("/ingredients/125").request().delete();
+		assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus());
+	}
+
+	@Test
+	public void testGetIngredientName() {
+		Ingredient ingredient = new Ingredient();
+		ingredient.setName("Chorizo");
+		long id = dao.insert(ingredient.getName());
+
+		Response response = target("ingredients/" + id + "/name").request().get();
+
+		assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+
+		assertEquals("Chorizo", response.readEntity(String.class));
+	}
+
+	@Test
+	public void testGetNotExistingIngredientName() {
+		Response response = target("ingredients/125/name").request().get();
+
+		assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus());
+	}
 }