Originally posted on whathebea.github.io on 21/10/2022
It has been a while since my last post but I swear I haven't given up! It's quite the opposite, actually.
I had to do a project for my internship program which was basically creating a Rest API and connecting it to an Android Application. As it turns out, connecting an API to an app is more of a chore than I thought it would be. I hope I can stick with web development.
I am not allowed to show all the code because it is stored in enterprise GitHub but I want to talk about everything I did and many some things that I struggled.
Android
First: These badges are way too cute for me NOT to use them.
I created the app on Android Studio and to make the HTTP requests I used RetroFit.
Android App Structure
API and Service
Before we move on to the activities I just want to take a look at the configuration for RetroFit.
API
In order to make RetroFit work we have to create an interface with the paths and types of HTTP requests we want to make. Since mine was a pretty simple application there wasn't much to write here.
public interface YourAPI {
@GET("/api/yourapi")
Call<List<MyEntity>> getAll();
@GET("/api/yourapi/{id}")
Call<MyEntity> getById(@Path("id") Long id);
}
The first get request is to retrieve a list of objects and the second one is to get a single one. You can read more about RetroFit here.
RetroFit Service
The Service part is pretty much standard.
public class RetrofitService {
private Retrofit retrofit;
public RetrofitService() {
initializeRetrofit();
}
private void initializeRetrofit() {
Gson gson = new GsonBuilder()
.create();
retrofit = new Retrofit.Builder()
.baseUrl("your_ip_address")
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
public Retrofit getRetrofit() {
return retrofit;
}
}
Activities
Some of the activities that I created are the following (these are not the actual names but I was trying to be descriptive about what each one is)
- Main Activity
- Splash Activity
- Get all Activity
- Get by ID Activity
Main Activity
This activity was the first one that was created together with the app. It was an empty activity and I added a logo + 2 buttons.
In Android Studio you can just click and drag components and you also have constraint layouts so, creating a simple screen is not that hard. After you create the screen with the components you have to access the Java Class and add your components so they can do something. Imagine you add a button and you give it the ID myButton, then you would retrieve it like this:
Button myButton = findViewById(R.id.myButton);
My buttons would redirect to another activity. To do that I had to take the button and use a onClickListener. Android Studio is quite useful because as long as you have an idea of what you are doing it does the job of creating most of the code structures for you.
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, GetAllActivity.class);
startActivity(intent);
}
});
So there you have it, that's all you have to do to change from one activity to another.
Splash Activity
The Splash Activity is simply a Splash that shows up when you open the app. I will be honest MINE DIDN'T TURN OUT BEAUTIFUL. I can't talk much about Splash Screens because I actually had to search a little bit about them. I found this medium article very thorough and helpful. I probably should work a little bit on my design skills…
Get All Activity
This screen is basically a list with information that was received from the API and so I had to use RecyclerView on it.
What is RecyclerView? you make ask yourself (or me). According to the Android Developer Docs:
RecyclerView makes it easy to efficiently display large sets of data. You supply the data and define how each item looks, and the RecyclerView library dynamically creates the elements when they're needed.
And honestly, couldn't have said it better than that myself. In order to use RecyclerView I created an extra layout: the list_item.xml. What is that? Well, it is what ONE item would look like. Take a look at the picture below for a second.
Do you see that the structure for each e-mail is the same and what changes is the content on each one? Well, that is a RecyclerView!
In this case the list_item.xml would have a name, a subject, the start of a message, how long ago it was sent and a start.
In order to use a RecyclerView you need an Adapter, you can read more about adapters on Android Developer Documentation
And how do we get the information now? Well, now it's finally RetroFit's time to shine!
- Create a method to load information
- Start retrofit service inside the method
- Using our API class with Retrofit
- Make the call
After you do all of that then you will have something like this:
private void loadInfo() {
RetrofitService retrofitService = new RetrofitService();
YourApi yourApi = retrofitService.getRetrofit().create(YourApi.class);
yourApi.getAll()
.enqueue(new Callback<List<MyEntity>>() {
@Override
public void onResponse(Call<List<MyEntity>> call, Response<List<MyEntity>> response) {
// what will you do with the response?
}
@Override
public void onFailure(Call<List<MyEntity>> call, Throwable t) {
// what will it do if it fails? e.g: a toast
}
});
}
Get by Id Activity
I think you can guess that this activity is pretty similar to the last one except we don't have a RecyclerView. It's just layout with what would be equivalent to a single item from the list.
The loadInfo method is almost exactly the same but one thing: I won't be calling or receiving a list.
Why did I struggle with RetroFit?
Looking back now the answer would be: because I didn't pay enough attention to small things.
Things like:
- Typos
- Mistaking the path for the requests
- Remembering that when I make the get request by ID I don't get an array of objects as a response, I get a single object
- Importing the wrong class
- Trying to make things much more complicated than what they truly are.
Spring
Spring was a MUCH easier ride than Android. Did I make mistakes? Nope! Where there things I could have done better? Most definitely yes. I made a checklist and I'll leave it here for you people to read it.
- [x] Create Project Structure (Spring Initializr)
- [x] Create Model
- [x] Create Controller
- [x] Service Layer Implementation
- [x] Create Repository to deal with database operations
- [x] Creating Dto and Dto converter
- [x] Unit tests on Controller layer
- [x] Unit tests on Service Layer
- [x] Connect API to MySql database
An api for big companies probably has much more than this but well, that's what I did.
Dependencies
- Spring Data JPA
- Spring Web
- Spring Boot Dev Tools
- MySql Driver
- SpringFox Boot Starter
- SpringFox Swagger 2
- SpringFox Swagger UI
Overview
Model
Here is an example of something the model should look like.
@Entity
@Table(name="YOURAPI")
public class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
// constructors
// getters and setters
}
It's pretty self-explanatory:
The @Entity annotation specifies that the class is an entity and is mapped to a database table. The @Table annotation specifies the name of the database table to be used for mapping. @id specifies that it is the primary key and @GeneratedValue specifies how it should be generated. Then we have a single @Column which specifies the name of the column.
After that, you just have your constructors and getters and setters. For my project I had a default constructor (empty) and two others, one with the id field and other without it. The getters and setters are also pretty standard, you can just generate them as you would. (Right Click > Source > Generate Getters and Setters)
Controller
There isn't anything special about the controller just like there wasn't with the model.
@RestController
@RequestMapping("/api/yourapi")
public class MyEntityController {
@Autowired
private MyService myService;
@GetMapping
public ResponseEntity<List<MyEntityDto>> getAll() {
return new ResponseEntity<>(myService.getAll(), HttpStatus.OK);
}
}
I actually forgot to put the @RestController annotation the first time I wrote the code and guess what? It didn't work. Don't forget your annotations!
@RequestMapping just maps the url path, you have @Autowired to do dependency injection of the service class and you have a pretty standard get request.
The DTO Pattern
DTO means Data Transfer Object. Is it a must? I am not sure. I mean, if you are just studying and making an api that will possibly never see the sunrise, then yeah, I would guess it's not a must. But as far as I've read it is an Enterprise application architecture pattern which means it solves problems in large systems. It's probably very interesting to know how it works.
The best explanation for the DTO pattern that I found is from Baeldung and I definitely would recommend the read!
Happy Endings
The happy ending is that I actually finished my project and can go back to studying Angular and keep finding more stuff to do. I came to the conclusion that I also must practice a little bit more of my designing skills because they are lacking quite a bit.
Besides that, everything is great! I focused a lot on Android here because my main issues were there and finding the solutions was not as easy as one would expect.
If you have any questions or want to know more about anything that I post here just contact me!
@whathebea on Twitter
Beatriz Gracia on Linkedin
Top comments (0)