add sunnah api (#210)

This commit is contained in:
Asim Aslam
2021-09-21 15:19:22 +01:00
committed by GitHub
parent 45c7f5b0bf
commit 6e40bfe06a
15 changed files with 2122 additions and 1 deletions

View File

@@ -8,8 +8,27 @@ import (
"net/http"
)
var (
keys = map[string]string{}
)
// Set a key within the header
func SetKey(k, v string) {
keys[k] = v
}
// Get a url and unmarshal a json body into the given value
func Get(url string, rsp interface{}) error {
resp, err := http.Get(url)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return err
}
for k, v := range keys {
req.Header.Set(k, v)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}

2
sunnah/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
sunnah

3
sunnah/Dockerfile Normal file
View File

@@ -0,0 +1,3 @@
FROM alpine
ADD sunnah /sunnah
ENTRYPOINT [ "/sunnah" ]

28
sunnah/Makefile Normal file
View File

@@ -0,0 +1,28 @@
GOPATH:=$(shell go env GOPATH)
.PHONY: init
init:
go get -u github.com/golang/protobuf/proto
go get -u github.com/golang/protobuf/protoc-gen-go
go get github.com/micro/micro/v3/cmd/protoc-gen-micro
go get github.com/micro/micro/v3/cmd/protoc-gen-openapi
.PHONY: api
api:
protoc --openapi_out=. --proto_path=. proto/sunnah.proto
.PHONY: proto
proto:
protoc --proto_path=. --micro_out=. --go_out=:. proto/sunnah.proto
.PHONY: build
build:
go build -o sunnah *.go
.PHONY: test
test:
go test -v ./... -cover
.PHONY: docker
docker:
docker build . -t sunnah:latest

10
sunnah/README.md Normal file
View File

@@ -0,0 +1,10 @@
Traditions and practices of the Islamic prophet, Muhammad (pbuh)
# Sunnah Service
Sunnah are the traditions and practices of the Islamic prophet, Muhammad, that constitute a model for Muslims to follow.
According to classical Islamic theories, the sunnah are documented by hadith (the verbally transmitted record of the teachings,
deeds and sayings, silent permissions or disapprovals of Muhammad), and along with the Quran (the book of Islam), are the divine
revelation (Wahy) delivered through Muhammad that make up the primary sources of Islamic law and belief/theology.
Powered by [Sunnah.com](https://sunnah.com).

80
sunnah/domain/domain.go Normal file
View File

@@ -0,0 +1,80 @@
package domain
type BookRequest struct {
Data []*Book `json:"data"`
Total int32 `json:"total"`
Limit int32 `json:"limit"`
}
type BookText struct {
Lang string `json:"lang"`
Name string `json:"name"`
}
type Book struct {
BookNumber string `json:"bookNumber"`
Book []*BookText `json:"book"`
HadithStartNumber int32 `json:"hadithStartNumber"`
HadithEndNumber int32 `json:"hadithEndNumber"`
NumberOfHadith int32 `json:"numberOfHadith"`
}
type ChaptersRequest struct {
Data []*Chapter `json:"data"`
Total int32 `json:"total"`
Limit int32 `json:"limit"`
}
type ChapterText struct {
Lang string `json:"lang"`
ChapterNumber string `json:"chapterNumber"`
ChapterTitle string `json:"chapterTitle"`
}
type Chapter struct {
BookNumber string `json:"bookNumber"`
ChapterId string `json:"chapterId"`
Chapter []*ChapterText `json:"chapter"`
}
type CollectionRequest struct {
Data []*Collection `json:"data"`
Total int32 `json:"total"`
Limit int32 `json:"limit"`
}
type CollectionText struct {
Lang string `json:"lang"`
Title string `json:"title"`
ShortIntro string `json:"shortIntro"`
}
type Collection struct {
Name string `json:"name"`
HasBooks bool `json:"hasBooks"`
HasChapters bool `json:"hasChapters"`
TotalHadith int32 `json:"totalHadith"`
TotalAvailableHadith int32 `json:"totalAvailableHadith"`
Collection []*CollectionText `json:"collection"`
}
type HadithsRequest struct {
Data []*Hadith `json:"data"`
Total int32 `json:"total"`
Limit int32 `json:"limit"`
}
type HadithText struct {
Lang string `json:"lang"`
ChapterNumber string `json:"chapterNumber"`
ChapterTitle string `json:"chapterTitle"`
Body string `json:"body"`
}
type Hadith struct {
Collection string `json:"collection"`
BookNumber string `json:"bookNumber"`
ChapterId string `json:"chapterId"`
HadithNumber string `json:"hadithNumber"`
Hadith []*HadithText `json:"hadith"`
}

99
sunnah/examples.json Normal file
View File

@@ -0,0 +1,99 @@
{
"collections": [{
"title": "List available collections",
"run_check": false,
"request": {},
"response": {
"collections": [{
"name": "bukhari",
"title": "Sahih al-Bukhari",
"arabic_title": "صحيح البخاري",
"summary": "Sahih al-Bukhari is a collection of hadith compiled by Imam Muhammad al-Bukhari (d. 256 AH/870 AD) (rahimahullah).\r\n\r\nHis collection is recognized by the overwhelming majority of the Muslim world to be the most authentic collection of reports of the \u003ci\u003eSunnah\u003c/i\u003e of the Prophet Muhammad (ﷺ). It contains over 7500 hadith (with repetitions) in 97 books.\r\n\r\nThe translation provided here is by Dr. M. Muhsin Khan.",
"hadiths": 7291
}]
}
}],
"books": [{
"title": "Get the books within a collection",
"run_check": false,
"request": {
"collection": "bukhari"
},
"response": {
"collection": "bukhari",
"total": 97,
"page": 1,
"limit": 50,
"books": [
{
"id": 1,
"name": "Revelation",
"arabic_name": "كتاب بدء الوحى ",
"hadiths": 7
},
{
"id": 2,
"name": "Belief",
"arabic_name": "كتاب الإيمان ",
"hadiths": 51
},
{
"id": 3,
"name": "Knowledge",
"arabic_name": "كتاب العلم ",
"hadiths": 76
}
]
}
],
"chapters": [{
"title": "List the chapters in a book",
"run_check": false,
"request": {
"collection": "bukhari",
"book": 1
},
"response": {
"collection": "bukhari",
"book": 1,
"page": 1,
"limit": 50,
"total": 6,
"chapters": [
{
"id": 1,
"key": "1.00",
"book": 1,
"title": "How the Divine Revelation started being revealed to Allah's Messenger",
"arabic_title": "باب كَيْفَ كَانَ بَدْءُ الْوَحْىِ إِلَى رَسُولِ اللَّهِ صلى الله عليه وسلم"
}
]
}
}],
"hadiths": [{
"title": "List the hadiths in a book",
"run_check": false,
"request": {
"collection": "bukhari",
"book": 1
},
"response": {
"collection": "bukhari",
"book": 1,
"page": 1,
"limit": 50,
"total": 7,
"hadiths": [
{
"id": 1,
"chapter": 1,
"chapter_key": "1.00",
"chapter_title": "How the Divine Revelation started being revealed to Allah's Messenger",
"arabic_chapter_title": "باب كَيْفَ كَانَ بَدْءُ الْوَحْىِ إِلَى رَسُولِ اللَّهِ صلى الله عليه وسلم",
"text": "\u003cp\u003eNarrated 'Umar bin Al-Khattab:\n\u003c/p\u003e\n\u003cp\u003e\n I heard Allah's Messenger (ﷺ) saying, \"The reward of deeds depends upon the \n intentions and every person will get the reward according to what he \n has intended. So whoever emigrated for worldly benefits or for a woman\n to marry, his emigration was for what he emigrated for.\"\n\u003c/p\u003e",
"arabic_text": "\u003cp\u003e[prematn]حَدَّثَنَا[narrator id=\"4698\" tooltip=\"عبد الله بن الزبير بن عيسى بن عبيد الله بن أسامة بن عبد الله بن حميد بن زهير بن الحارث بن أسد بن عبد العزى\"] الْحُمَيْدِيُّ عَبْدُ اللَّهِ بْنُ الزُّبَيْرِ [/narrator]، قَالَ : حَدَّثَنَا[narrator id=\"3443\" tooltip=\"سفيان بن عيينة بن ميمون\"] سُفْيَانُ [/narrator]، قَالَ : حَدَّثَنَا[narrator id=\"8272\" tooltip=\"يحيى بن سعيد بن قيس بن عمرو بن سهل بن ثعلبة بن الحارث بن زيد بن ثعلبة بن غنم بن مالك بن النجار\"] يَحْيَى بْنُ سَعِيدٍ الْأَنْصَارِيُّ [/narrator]، قَالَ : أَخْبَرَنِي[narrator id=\"6796\" tooltip=\"محمد بن إبراهيم بن الحارث بن خالد بن صخر بن عامر بن كعب بن سعد بن تيم بن مرة\"] مُحَمَّدُ بْنُ إِبْرَاهِيمَ التَّيْمِيُّ [/narrator]، أَنَّهُ سَمِعَ[narrator id=\"5719\" tooltip=\"علقمة بن وقاص بن محصن بن كلدة بن عبد ياليل\"] عَلْقَمَةَ بْنَ وَقَّاصٍ اللَّيْثِيَّ [/narrator]، يَقُولُ : سَمِعْتُ[narrator id=\"5913\" tooltip=\"عمر بن الخطاب بن نفيل بن عبد العزى بن رياح بن عبد الله بن قرط بن رزاح بن عدي بن كعب\"] عُمَرَ بْنَ الْخَطَّابِ [/narrator] رَضِيَ اللَّهُ عَنْهُ عَلَى الْمِنْبَرِ، قَالَ : سَمِعْتُ رَسُولَ اللَّهِ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ، يَقُولُ : \"[/prematn]\n[matn]إِنَّمَا الْأَعْمَالُ بِالنِّيَّاتِ، وَإِنَّمَا لِكُلِّ امْرِئٍ مَا نَوَى، فَمَنْ كَانَتْ هِجْرَتُهُ إِلَى دُنْيَا يُصِيبُهَا أَوْ إِلَى امْرَأَةٍ يَنْكِحُهَا، فَهِجْرَتُهُ إِلَى مَا هَاجَرَ إِلَيْهِ \"[/matn]\u003c/p\u003e"
}
]
}
}]
}

3
sunnah/generate.go Normal file
View File

@@ -0,0 +1,3 @@
package main
//go:generate make proto

231
sunnah/handler/sunnah.go Normal file
View File

@@ -0,0 +1,231 @@
package handler
import (
"context"
"fmt"
"strconv"
"strings"
"github.com/micro/micro/v3/service/errors"
"github.com/micro/micro/v3/service/logger"
"github.com/micro/services/pkg/api"
"github.com/micro/services/sunnah/domain"
pb "github.com/micro/services/sunnah/proto"
)
var (
apiUrl = "https://api.sunnah.com/v1/"
)
type Sunnah struct {
apiKey string
}
func New(key string) *Sunnah {
api.SetKey("X-API-Key", key)
return &Sunnah{
apiKey: key,
}
}
func (s *Sunnah) Collections(ctx context.Context, req *pb.CollectionsRequest, rsp *pb.CollectionsResponse) error {
var resp *domain.CollectionRequest
if req.Limit <= 0 {
req.Limit = 50
}
if req.Page <= 0 {
req.Page = 1
}
uri := fmt.Sprintf("%scollections?limit=%d&page=%d", apiUrl, req.Limit, req.Page)
if err := api.Get(uri, &resp); err != nil {
logger.Errorf("Failed to retrieve collections: %v", err)
return errors.InternalServerError("sunnah.collections", "Failed to retrieve collections")
}
for _, c := range resp.Data {
var arabicTitle string
if len(c.Collection) > 1 && c.Collection[1].Lang == "ar" {
arabicTitle = c.Collection[1].Title
}
rsp.Collections = append(rsp.Collections, &pb.Collection{
Name: c.Name,
Title: c.Collection[0].Title,
ArabicTitle: arabicTitle,
Hadiths: c.TotalHadith,
Summary: c.Collection[0].ShortIntro,
})
}
return nil
}
func (s *Sunnah) Books(ctx context.Context, req *pb.BooksRequest, rsp *pb.BooksResponse) error {
var resp *domain.BookRequest
if len(req.Collection) == 0 {
return errors.BadRequest("sunnah.books", "missing collection name")
}
if req.Limit <= 0 {
req.Limit = 50
}
if req.Page <= 0 {
req.Page = 1
}
uri := fmt.Sprintf("%scollections/%s/books?limit=%d&page=%d", apiUrl, req.Collection, req.Limit, req.Page)
if err := api.Get(uri, &resp); err != nil {
logger.Errorf("Failed to retrieve books: %v", err)
return errors.InternalServerError("sunnah.books", "Failed to retrieve books")
}
rsp.Collection = req.Collection
rsp.Total = resp.Total
rsp.Limit = req.Limit
rsp.Page = req.Page
for _, b := range resp.Data {
if len(b.Book) == 0 {
continue
}
var arabicName string
if len(b.Book) > 1 && b.Book[1].Lang == "ar" {
arabicName = b.Book[1].Name
}
bkId, _ := strconv.Atoi(b.BookNumber)
rsp.Books = append(rsp.Books, &pb.Book{
Id: int32(bkId),
Name: b.Book[0].Name,
ArabicName: arabicName,
Hadiths: b.NumberOfHadith,
})
}
return nil
}
func (s *Sunnah) Chapters(ctx context.Context, req *pb.ChaptersRequest, rsp *pb.ChaptersResponse) error {
var resp *domain.ChaptersRequest
if len(req.Collection) == 0 {
return errors.BadRequest("sunnah.chapters", "missing collection name")
}
if req.Book == 0 {
req.Book = 1
}
if req.Limit <= 0 {
req.Limit = 50
}
if req.Page <= 0 {
req.Page = 1
}
uri := fmt.Sprintf("%scollections/%s/books/%d/chapters?limit=%d&page=%d", apiUrl, req.Collection, req.Book, req.Limit, req.Page)
if err := api.Get(uri, &resp); err != nil {
logger.Errorf("Failed to retrieve chapters: %v", err)
return errors.InternalServerError("sunnah.chapters", "Failed to retrieve chapters")
}
rsp.Collection = req.Collection
rsp.Book = req.Book
rsp.Total = resp.Total
rsp.Limit = req.Limit
rsp.Page = req.Page
for _, c := range resp.Data {
if len(c.Chapter) == 0 {
continue
}
var arabicTitle string
if len(c.Chapter) > 1 && c.Chapter[1].Lang == "ar" {
arabicTitle = c.Chapter[1].ChapterTitle
}
bkId, _ := strconv.Atoi(c.BookNumber)
chNumber, _ := strconv.Atoi(strings.Split(c.ChapterId, ".")[0])
rsp.Chapters = append(rsp.Chapters, &pb.Chapter{
Id: int32(chNumber),
Key: c.ChapterId,
Book: int32(bkId),
Title: c.Chapter[0].ChapterTitle,
ArabicTitle: arabicTitle,
})
}
return nil
}
func (s *Sunnah) Hadiths(ctx context.Context, req *pb.HadithsRequest, rsp *pb.HadithsResponse) error {
var resp *domain.HadithsRequest
if len(req.Collection) == 0 {
return errors.BadRequest("sunnah.hadiths", "missing collection name")
}
if req.Book == 0 {
req.Book = 1
}
if req.Limit <= 0 {
req.Limit = 50
}
if req.Page <= 0 {
req.Page = 1
}
uri := fmt.Sprintf("%scollections/%s/books/%d/hadiths?limit=%d&page=%d", apiUrl, req.Collection, req.Book, req.Limit, req.Page)
if err := api.Get(uri, &resp); err != nil {
logger.Errorf("Failed to retrieve hadiths: %v", err)
return errors.InternalServerError("sunnah.hadiths", "Failed to retrieve hadiths")
}
rsp.Collection = req.Collection
rsp.Book = req.Book
rsp.Total = resp.Total
rsp.Limit = req.Limit
rsp.Page = req.Page
for _, h := range resp.Data {
if len(h.Hadith) == 0 {
continue
}
var arabicTitle string
var arabicText string
if len(h.Hadith) > 1 && h.Hadith[1].Lang == "ar" {
arabicTitle = h.Hadith[1].ChapterTitle
arabicText = h.Hadith[1].Body
}
chNumber, _ := strconv.Atoi(strings.Split(h.ChapterId, ".")[0])
hId, _ := strconv.Atoi(h.HadithNumber)
rsp.Hadiths = append(rsp.Hadiths, &pb.Hadith{
Id: int32(hId),
Chapter: int32(chNumber),
ChapterKey: h.ChapterId,
ChapterTitle: h.Hadith[0].ChapterTitle,
Text: h.Hadith[0].Body,
ArabicText: arabicText,
ArabicChapterTitle: arabicTitle,
})
}
return nil
}

34
sunnah/main.go Normal file
View File

@@ -0,0 +1,34 @@
package main
import (
"github.com/micro/micro/v3/service"
"github.com/micro/micro/v3/service/config"
"github.com/micro/micro/v3/service/logger"
"github.com/micro/services/sunnah/handler"
pb "github.com/micro/services/sunnah/proto"
)
func main() {
// Create service
srv := service.New(
service.Name("sunnah"),
service.Version("latest"),
)
v, err := config.Get("sunnah.api_key")
if err != nil {
logger.Fatalf("sunnha.api_key config not found: %v", err)
}
key := v.String("")
if len(key) == 0 {
logger.Fatal("sunnah.api_key config not found")
}
// Register handler
pb.RegisterSunnahHandler(srv.Server(), handler.New(key))
// Run service
if err := srv.Run(); err != nil {
logger.Fatal(err)
}
}

1
sunnah/micro.mu Normal file
View File

@@ -0,0 +1 @@
service sunnah

1304
sunnah/proto/sunnah.pb.go Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,144 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: proto/sunnah.proto
package sunnah
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
import (
context "context"
api "github.com/micro/micro/v3/service/api"
client "github.com/micro/micro/v3/service/client"
server "github.com/micro/micro/v3/service/server"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
// Reference imports to suppress errors if they are not otherwise used.
var _ api.Endpoint
var _ context.Context
var _ client.Option
var _ server.Option
// Api Endpoints for Sunnah service
func NewSunnahEndpoints() []*api.Endpoint {
return []*api.Endpoint{}
}
// Client API for Sunnah service
type SunnahService interface {
Collections(ctx context.Context, in *CollectionsRequest, opts ...client.CallOption) (*CollectionsResponse, error)
Books(ctx context.Context, in *BooksRequest, opts ...client.CallOption) (*BooksResponse, error)
Chapters(ctx context.Context, in *ChaptersRequest, opts ...client.CallOption) (*ChaptersResponse, error)
Hadiths(ctx context.Context, in *HadithsRequest, opts ...client.CallOption) (*HadithsResponse, error)
}
type sunnahService struct {
c client.Client
name string
}
func NewSunnahService(name string, c client.Client) SunnahService {
return &sunnahService{
c: c,
name: name,
}
}
func (c *sunnahService) Collections(ctx context.Context, in *CollectionsRequest, opts ...client.CallOption) (*CollectionsResponse, error) {
req := c.c.NewRequest(c.name, "Sunnah.Collections", in)
out := new(CollectionsResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sunnahService) Books(ctx context.Context, in *BooksRequest, opts ...client.CallOption) (*BooksResponse, error) {
req := c.c.NewRequest(c.name, "Sunnah.Books", in)
out := new(BooksResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sunnahService) Chapters(ctx context.Context, in *ChaptersRequest, opts ...client.CallOption) (*ChaptersResponse, error) {
req := c.c.NewRequest(c.name, "Sunnah.Chapters", in)
out := new(ChaptersResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *sunnahService) Hadiths(ctx context.Context, in *HadithsRequest, opts ...client.CallOption) (*HadithsResponse, error) {
req := c.c.NewRequest(c.name, "Sunnah.Hadiths", in)
out := new(HadithsResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Sunnah service
type SunnahHandler interface {
Collections(context.Context, *CollectionsRequest, *CollectionsResponse) error
Books(context.Context, *BooksRequest, *BooksResponse) error
Chapters(context.Context, *ChaptersRequest, *ChaptersResponse) error
Hadiths(context.Context, *HadithsRequest, *HadithsResponse) error
}
func RegisterSunnahHandler(s server.Server, hdlr SunnahHandler, opts ...server.HandlerOption) error {
type sunnah interface {
Collections(ctx context.Context, in *CollectionsRequest, out *CollectionsResponse) error
Books(ctx context.Context, in *BooksRequest, out *BooksResponse) error
Chapters(ctx context.Context, in *ChaptersRequest, out *ChaptersResponse) error
Hadiths(ctx context.Context, in *HadithsRequest, out *HadithsResponse) error
}
type Sunnah struct {
sunnah
}
h := &sunnahHandler{hdlr}
return s.Handle(s.NewHandler(&Sunnah{h}, opts...))
}
type sunnahHandler struct {
SunnahHandler
}
func (h *sunnahHandler) Collections(ctx context.Context, in *CollectionsRequest, out *CollectionsResponse) error {
return h.SunnahHandler.Collections(ctx, in, out)
}
func (h *sunnahHandler) Books(ctx context.Context, in *BooksRequest, out *BooksResponse) error {
return h.SunnahHandler.Books(ctx, in, out)
}
func (h *sunnahHandler) Chapters(ctx context.Context, in *ChaptersRequest, out *ChaptersResponse) error {
return h.SunnahHandler.Chapters(ctx, in, out)
}
func (h *sunnahHandler) Hadiths(ctx context.Context, in *HadithsRequest, out *HadithsResponse) error {
return h.SunnahHandler.Hadiths(ctx, in, out)
}

158
sunnah/proto/sunnah.proto Normal file
View File

@@ -0,0 +1,158 @@
syntax = "proto3";
package sunnah;
option go_package = "./proto;sunnah";
service Sunnah {
rpc Collections(CollectionsRequest) returns (CollectionsResponse) {}
rpc Books(BooksRequest) returns (BooksResponse) {}
rpc Chapters(ChaptersRequest) returns (ChaptersResponse) {}
rpc Hadiths(HadithsRequest) returns (HadithsResponse) {}
}
message Collection {
// Name of the collection e.g bukhari
string name = 1;
// Title of the collection e.g Sahih al-Bukhari
string title = 2;
// Arabic title if available
string arabic_title = 3;
// An introduction explaining the collection
string summary = 4;
// Total hadiths in the collection
int32 hadiths = 5;
}
message Book {
// number of the book e.g 1
int32 id = 1;
// name of the book
string name = 2;
// arabic name of the book
string arabic_name = 3;
// number of hadiths in the book
int32 hadiths = 4;
}
message Chapter {
// the chapter id e.g 1
int32 id = 1;
// the chapter key e.g 1.00
string key = 2;
// the book number
int32 book = 3;
// title of the chapter
string title = 4;
// arabic title
string arabic_title = 5;
}
message Hadith {
// hadith id
int32 id = 1;
// the chapter id
int32 chapter = 2;
// the chapter key
string chapter_key = 3;
// the chapter title
string chapter_title = 4;
// the arabic chapter title
string arabic_chapter_title = 5;
// hadith text
string text = 6;
// the arabic text
string arabic_text = 7;
}
// Get a list of available collections. A collection is
// a compilation of hadiths collected and written by an author.
message CollectionsRequest {
// The page in the pagination
int32 page = 1;
// Number of collections to limit to
int32 limit = 2;
}
message CollectionsResponse {
repeated Collection collections = 1;
}
// Get a list of books from within a collection. A book can contain many chapters
// each with its own hadiths.
message BooksRequest {
// Name of the collection
string collection = 1;
// The page in the pagination
int32 page = 2;
// Limit the number of books returned
int32 limit = 3;
}
message BooksResponse {
// Name of the collection
string collection = 1;
// The total overall books
int32 total = 2;
// The page requested
int32 page = 3;
// The limit specified
int32 limit = 4;
// A list of books
repeated Book books = 5;
}
// Get all the chapters of a given book within a collection.
message ChaptersRequest {
// name of the collection
string collection = 1;
// number of the book
int32 book = 2;
// The page in the pagination
int32 page = 3;
// Limit the number of chapters returned
int32 limit = 4;
}
message ChaptersResponse {
// name of the collection
string collection = 1;
// number of the book
int32 book = 2;
// The page in the pagination
int32 page = 3;
// Limit the number of chapters returned
int32 limit = 4;
// Total chapters in the book
int32 total = 5;
// The chapters of the book
repeated Chapter chapters = 6;
}
// Hadiths returns a list of hadiths and their corresponding text for a
// given book within a collection.
message HadithsRequest {
// name of the collection
string collection = 1;
// number of the book
int32 book = 2;
// The page in the pagination
int32 page = 3;
// Limit the number of hadiths
int32 limit = 4;
}
message HadithsResponse {
// name of the collection
string collection = 1;
// number of the book
int32 book = 2;
// The page in the pagination
int32 page = 3;
// Limit the number of hadiths returned
int32 limit = 4;
// Total hadiths in the book
int32 total = 5;
// The hadiths of the book
repeated Hadith hadiths = 7;
}

5
sunnah/publicapi.json Normal file
View File

@@ -0,0 +1,5 @@
{
"name": "sunnah",
"icon": "📖",
"category": "religion"
}